diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-03 19:22:17 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-02-28 03:05:38 -0900 |
commit | a5b5eba7f788bb77cf57f9c94f3474a2d439ab0b (patch) | |
tree | 278813d1b1a9024174531376d41a2ba04a3b27f6 /libbcache/fs.c | |
parent | e4d1c93d85a5b86c04599bfc9f658308d741fd41 (diff) |
New on disk format - encryption
Diffstat (limited to 'libbcache/fs.c')
-rw-r--r-- | libbcache/fs.c | 156 |
1 files changed, 84 insertions, 72 deletions
diff --git a/libbcache/fs.c b/libbcache/fs.c index 884a950..76948e7 100644 --- a/libbcache/fs.c +++ b/libbcache/fs.c @@ -26,7 +26,9 @@ static struct kmem_cache *bch_inode_cache; -static void bch_vfs_inode_init(struct bch_inode_info *, struct bkey_s_c_inode); +static void bch_vfs_inode_init(struct cache_set *, + struct bch_inode_info *, + struct bch_inode_unpacked *); /* * I_SIZE_DIRTY requires special handling: @@ -63,11 +65,20 @@ int __must_check __bch_write_inode(struct cache_set *c, { struct btree_iter iter; struct inode *inode = &ei->vfs_inode; - struct bkey_i_inode new_inode; - struct bch_inode *bi; + struct bch_inode_unpacked inode_u; + struct bkey_inode_buf inode_p; u64 inum = inode->i_ino; + unsigned i_nlink = READ_ONCE(inode->i_nlink); int ret; + /* + * We can't write an inode with i_nlink == 0 because it's stored biased; + * however, we don't need to because if i_nlink is 0 the inode is + * getting deleted when it's evicted. + */ + if (!i_nlink) + return 0; + lockdep_assert_held(&ei->update_lock); bch_btree_iter_init_intent(&iter, c, BTREE_ID_INODES, POS(inum, 0)); @@ -84,33 +95,41 @@ int __must_check __bch_write_inode(struct cache_set *c, return -ENOENT; } - bkey_reassemble(&new_inode.k_i, k); - bi = &new_inode.v; + ret = bch_inode_unpack(bkey_s_c_to_inode(k), &inode_u); + if (WARN_ONCE(ret, + "error %i unpacking inode %llu", ret, inum)) { + ret = -ENOENT; + break; + } if (set) { - ret = set(ei, bi, p); + ret = set(ei, &inode_u, p); if (ret) goto out; } - bi->i_mode = cpu_to_le16(inode->i_mode); - bi->i_uid = cpu_to_le32(i_uid_read(inode)); - bi->i_gid = cpu_to_le32(i_gid_read(inode)); - bi->i_nlink = cpu_to_le32(inode->i_nlink); - bi->i_dev = cpu_to_le32(inode->i_rdev); - bi->i_atime = cpu_to_le64(timespec_to_ns(&inode->i_atime)); - bi->i_mtime = cpu_to_le64(timespec_to_ns(&inode->i_mtime)); - bi->i_ctime = cpu_to_le64(timespec_to_ns(&inode->i_ctime)); + BUG_ON(i_nlink < nlink_bias(inode->i_mode)); + + inode_u.i_mode = inode->i_mode; + inode_u.i_uid = i_uid_read(inode); + inode_u.i_gid = i_gid_read(inode); + inode_u.i_nlink = i_nlink - nlink_bias(inode->i_mode); + inode_u.i_dev = inode->i_rdev; + inode_u.i_atime = timespec_to_bch_time(c, inode->i_atime); + inode_u.i_mtime = timespec_to_bch_time(c, inode->i_mtime); + inode_u.i_ctime = timespec_to_bch_time(c, inode->i_ctime); + + bch_inode_pack(&inode_p, &inode_u); ret = bch_btree_insert_at(c, NULL, NULL, &ei->journal_seq, BTREE_INSERT_ATOMIC| BTREE_INSERT_NOFAIL, - BTREE_INSERT_ENTRY(&iter, &new_inode.k_i)); + BTREE_INSERT_ENTRY(&iter, &inode_p.inode.k_i)); } while (ret == -EINTR); if (!ret) { - ei->i_size = le64_to_cpu(bi->i_size); - ei->i_flags = le32_to_cpu(bi->i_flags); + ei->i_size = inode_u.i_size; + ei->i_flags = inode_u.i_flags; } out: bch_btree_iter_unlock(&iter); @@ -138,7 +157,7 @@ int bch_inc_nlink(struct cache_set *c, struct bch_inode_info *ei) int bch_dec_nlink(struct cache_set *c, struct bch_inode_info *ei) { - int ret; + int ret = 0; mutex_lock(&ei->update_lock); drop_nlink(&ei->vfs_inode); @@ -152,9 +171,8 @@ static struct inode *bch_vfs_inode_get(struct super_block *sb, u64 inum) { struct cache_set *c = sb->s_fs_info; struct inode *inode; + struct bch_inode_unpacked inode_u; struct bch_inode_info *ei; - struct btree_iter iter; - struct bkey_s_c k; int ret; pr_debug("inum %llu", inum); @@ -165,24 +183,19 @@ static struct inode *bch_vfs_inode_get(struct super_block *sb, u64 inum) if (!(inode->i_state & I_NEW)) return inode; - bch_btree_iter_init(&iter, c, BTREE_ID_INODES, POS(inum, 0)); - k = bch_btree_iter_peek_with_holes(&iter); - - if ((ret = btree_iter_err(k)) || k.k->type != BCH_INODE_FS) { - ret = bch_btree_iter_unlock(&iter); + ret = bch_inode_find_by_inum(c, inum, &inode_u); + if (ret) { iget_failed(inode); - return ERR_PTR(ret ?: -ENOENT); + return ERR_PTR(ret); } ei = to_bch_ei(inode); - bch_vfs_inode_init(ei, bkey_s_c_to_inode(k)); + bch_vfs_inode_init(c, ei, &inode_u); ei->journal_seq = bch_inode_journal_seq(&c->journal, inum); unlock_new_inode(inode); - bch_btree_iter_unlock(&iter); - return inode; } @@ -193,7 +206,8 @@ static struct inode *bch_vfs_inode_create(struct cache_set *c, struct inode *inode; struct posix_acl *default_acl = NULL, *acl = NULL; struct bch_inode_info *ei; - struct bkey_i_inode bkey_inode; + struct bch_inode_unpacked inode_u; + struct bkey_inode_buf inode_p; int ret; inode = new_inode(parent->i_sb); @@ -210,10 +224,11 @@ static struct inode *bch_vfs_inode_create(struct cache_set *c, ei = to_bch_ei(inode); - bch_inode_init(c, &bkey_inode, i_uid_read(inode), + bch_inode_init(c, &inode_u, i_uid_read(inode), i_gid_read(inode), inode->i_mode, rdev); + bch_inode_pack(&inode_p, &inode_u); - ret = bch_inode_create(c, &bkey_inode.k_i, + ret = bch_inode_create(c, &inode_p.inode.k_i, BLOCKDEV_INODE_MAX, 0, &c->unused_inode_hint); if (unlikely(ret)) { @@ -225,7 +240,8 @@ static struct inode *bch_vfs_inode_create(struct cache_set *c, goto err; } - bch_vfs_inode_init(ei, inode_i_to_s_c(&bkey_inode)); + inode_u.inum = inode_p.inode.k.p.inode; + bch_vfs_inode_init(c, ei, &inode_u); if (default_acl) { ret = bch_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); @@ -266,7 +282,7 @@ static int bch_vfs_dirent_create(struct cache_set *c, struct inode *dir, if (unlikely(ret)) return ret; - dir->i_mtime = dir->i_ctime = CURRENT_TIME; + dir->i_mtime = dir->i_ctime = current_fs_time(dir->i_sb); mark_inode_dirty_sync(dir); return 0; } @@ -337,7 +353,7 @@ static int bch_link(struct dentry *old_dentry, struct inode *dir, lockdep_assert_held(&inode->i_rwsem); - inode->i_ctime = CURRENT_TIME; + inode->i_ctime = current_fs_time(dir->i_sb); ret = bch_inc_nlink(c, ei); if (ret) @@ -382,12 +398,7 @@ static int bch_unlink(struct inode *dir, struct dentry *dentry) drop_nlink(inode); } - drop_nlink(inode); - if (inode->i_nlink) { - mutex_lock(&ei->update_lock); - ret = bch_write_inode(c, ei); - mutex_unlock(&ei->update_lock); - } + bch_dec_nlink(c, ei); return 0; } @@ -473,7 +484,7 @@ static int bch_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *old_inode = old_dentry->d_inode; struct bch_inode_info *ei = to_bch_ei(old_inode); struct inode *new_inode = new_dentry->d_inode; - struct timespec now = CURRENT_TIME; + struct timespec now = current_fs_time(old_dir->i_sb); int ret; lockdep_assert_held(&old_dir->i_rwsem); @@ -550,7 +561,7 @@ static int bch_rename_exchange(struct inode *old_dir, struct dentry *old_dentry, struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; struct bch_inode_info *ei = to_bch_ei(old_inode); - struct timespec now = CURRENT_TIME; + struct timespec now = current_fs_time(old_dir->i_sb); int ret; ret = bch_dirent_rename(c, @@ -783,14 +794,14 @@ static unsigned bch_inode_flags_to_user_flags(unsigned flags) } static int bch_inode_user_flags_set(struct bch_inode_info *ei, - struct bch_inode *bi, + struct bch_inode_unpacked *bi, void *p) { /* * We're relying on btree locking here for exclusion with other ioctl * calls - use the flags in the btree (@bi), not ei->i_flags: */ - unsigned bch_flags = le32_to_cpu(bi->i_flags); + unsigned bch_flags = bi->i_flags; unsigned oldflags = bch_inode_flags_to_user_flags(bch_flags); unsigned newflags = *((unsigned *) p); unsigned i; @@ -812,8 +823,8 @@ static int bch_inode_user_flags_set(struct bch_inode_info *ei, if (oldflags != newflags) return -EOPNOTSUPP; - bi->i_flags = cpu_to_le32(bch_flags); - ei->vfs_inode.i_ctime = CURRENT_TIME; + bi->i_flags = bch_flags; + ei->vfs_inode.i_ctime = current_fs_time(ei->vfs_inode.i_sb); return 0; } @@ -1010,32 +1021,33 @@ static const struct address_space_operations bch_address_space_operations = { .error_remove_page = generic_error_remove_page, }; -static void bch_vfs_inode_init(struct bch_inode_info *ei, - struct bkey_s_c_inode bkey_inode) +static void bch_vfs_inode_init(struct cache_set *c, + struct bch_inode_info *ei, + struct bch_inode_unpacked *bi) { struct inode *inode = &ei->vfs_inode; - const struct bch_inode *bi = bkey_inode.v; pr_debug("init inode %llu with mode %o", - bkey_inode.k->p.inode, bi->i_mode); - - ei->i_flags = le32_to_cpu(bi->i_flags); - ei->i_size = le64_to_cpu(bi->i_size); - - inode->i_mode = le16_to_cpu(bi->i_mode); - i_uid_write(inode, le32_to_cpu(bi->i_uid)); - i_gid_write(inode, le32_to_cpu(bi->i_gid)); - - atomic64_set(&ei->i_sectors, le64_to_cpu(bi->i_sectors)); - inode->i_blocks = atomic64_read(&ei->i_sectors); - - inode->i_ino = bkey_inode.k->p.inode; - set_nlink(inode, le32_to_cpu(bi->i_nlink)); - inode->i_rdev = le32_to_cpu(bi->i_dev); - inode->i_size = le64_to_cpu(bi->i_size); - inode->i_atime = ns_to_timespec(le64_to_cpu(bi->i_atime)); - inode->i_mtime = ns_to_timespec(le64_to_cpu(bi->i_mtime)); - inode->i_ctime = ns_to_timespec(le64_to_cpu(bi->i_ctime)); + bi->inum, bi->i_mode); + + ei->i_flags = bi->i_flags; + ei->i_size = bi->i_size; + + inode->i_mode = bi->i_mode; + i_uid_write(inode, bi->i_uid); + i_gid_write(inode, bi->i_gid); + + atomic64_set(&ei->i_sectors, bi->i_sectors); + inode->i_blocks = bi->i_sectors; + + inode->i_ino = bi->inum; + set_nlink(inode, bi->i_nlink + nlink_bias(inode->i_mode)); + inode->i_rdev = bi->i_dev; + inode->i_generation = bi->i_generation; + inode->i_size = bi->i_size; + inode->i_atime = bch_time_to_timespec(c, bi->i_atime); + inode->i_mtime = bch_time_to_timespec(c, bi->i_mtime); + inode->i_ctime = bch_time_to_timespec(c, bi->i_ctime); bch_inode_flags_to_vfs(inode); ei->str_hash = bch_hash_info_init(bi); @@ -1149,8 +1161,8 @@ static int bch_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_files = atomic_long_read(&c->nr_inodes); buf->f_ffree = U64_MAX; - fsid = le64_to_cpup((void *) c->disk_sb.user_uuid.b) ^ - le64_to_cpup((void *) c->disk_sb.user_uuid.b + sizeof(u64)); + fsid = le64_to_cpup((void *) c->sb.user_uuid.b) ^ + le64_to_cpup((void *) c->sb.user_uuid.b + sizeof(u64)); buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; buf->f_namelen = NAME_MAX; @@ -1380,7 +1392,7 @@ static struct dentry *bch_mount(struct file_system_type *fs_type, sb->s_op = &bch_super_operations; sb->s_xattr = bch_xattr_handlers; sb->s_magic = BCACHE_STATFS_MAGIC; - sb->s_time_gran = 1; + sb->s_time_gran = c->sb.time_precision; c->vfs_sb = sb; sb->s_bdi = &c->bdi; |