]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
f2fs crypto: add filename encryption for roll-forward recovery
authorJaegeuk Kim <jaegeuk@kernel.org>
Thu, 30 Apr 2015 00:02:18 +0000 (17:02 -0700)
committerJaegeuk Kim <jaegeuk@kernel.org>
Thu, 28 May 2015 22:41:55 +0000 (15:41 -0700)
This patch adds a bit flag to indicate whether or not i_name in the inode
is encrypted.

If this name is encrypted, we can't do recover_dentry during roll-forward.
So, f2fs_sync_file() needs to do checkpoint, if this will be needed in future.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/dir.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/namei.c
fs/f2fs/recovery.c

index 5e10d9d8099c654e1e33364d835d973e4af17edb..12f686914d387f3fbc80e19537ea90b4e0bc6b0a 100644 (file)
@@ -314,10 +314,14 @@ static void init_dent_inode(const struct qstr *name, struct page *ipage)
        set_page_dirty(ipage);
 }
 
-int update_dent_inode(struct inode *inode, const struct qstr *name)
+int update_dent_inode(struct inode *inode, struct inode *to,
+                                       const struct qstr *name)
 {
        struct page *page;
 
+       if (file_enc_name(to))
+               return 0;
+
        page = get_node_page(F2FS_I_SB(inode), inode->i_ino);
        if (IS_ERR(page))
                return PTR_ERR(page);
@@ -597,6 +601,8 @@ add_dentry:
                        err = PTR_ERR(page);
                        goto fail;
                }
+               if (f2fs_encrypted_inode(dir))
+                       file_set_enc_name(inode);
        }
 
        make_dentry_ptr(NULL, &d, (void *)dentry_blk, 1);
index 6f4d1dbac2f481e9974dc0c95f5842a412094c00..ea4f48f3073c682023ab126adc16ad2d92957951 100644 (file)
@@ -378,6 +378,7 @@ struct f2fs_map_blocks {
 #define FADVISE_COLD_BIT       0x01
 #define FADVISE_LOST_PINO_BIT  0x02
 #define FADVISE_ENCRYPT_BIT    0x04
+#define FADVISE_ENC_NAME_BIT   0x08
 
 #define file_is_cold(inode)    is_file(inode, FADVISE_COLD_BIT)
 #define file_wrong_pino(inode) is_file(inode, FADVISE_LOST_PINO_BIT)
@@ -388,6 +389,8 @@ struct f2fs_map_blocks {
 #define file_is_encrypt(inode) is_file(inode, FADVISE_ENCRYPT_BIT)
 #define file_set_encrypt(inode)        set_file(inode, FADVISE_ENCRYPT_BIT)
 #define file_clear_encrypt(inode) clear_file(inode, FADVISE_ENCRYPT_BIT)
+#define file_enc_name(inode)   is_file(inode, FADVISE_ENC_NAME_BIT)
+#define file_set_enc_name(inode) set_file(inode, FADVISE_ENC_NAME_BIT)
 
 /* Encryption algorithms */
 #define F2FS_ENCRYPTION_MODE_INVALID           0
@@ -1602,7 +1605,7 @@ struct f2fs_dir_entry *f2fs_parent_dir(struct inode *, struct page **);
 ino_t f2fs_inode_by_name(struct inode *, struct qstr *);
 void f2fs_set_link(struct inode *, struct f2fs_dir_entry *,
                                struct page *, struct inode *);
-int update_dent_inode(struct inode *, const struct qstr *);
+int update_dent_inode(struct inode *, struct inode *, const struct qstr *);
 void f2fs_update_dentry(nid_t ino, umode_t mode, struct f2fs_dentry_ptr *,
                        const struct qstr *, f2fs_hash_t , unsigned int);
 int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *, nid_t,
index 452123ecd8fcc563c2ed722007b9b8addd0c0c8a..cb0d6b68020a1610e265daaf6b463aa56bf5a68e 100644 (file)
@@ -106,7 +106,7 @@ static int get_parent_ino(struct inode *inode, nid_t *pino)
        if (!dentry)
                return 0;
 
-       if (update_dent_inode(inode, &dentry->d_name)) {
+       if (update_dent_inode(inode, inode, &dentry->d_name)) {
                dput(dentry);
                return 0;
        }
@@ -123,6 +123,8 @@ static inline bool need_do_checkpoint(struct inode *inode)
 
        if (!S_ISREG(inode->i_mode) || inode->i_nlink != 1)
                need_cp = true;
+       else if (file_enc_name(inode) && need_dentry_mark(sbi, inode->i_ino))
+               need_cp = true;
        else if (file_wrong_pino(inode))
                need_cp = true;
        else if (!space_for_roll_forward(sbi))
index bc8992e8137e7c6b688655546257aa13289fe078..c857f8249da0901d2f682ca9bd3d6049d5735e89 100644 (file)
@@ -517,7 +517,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
                if (err)
                        goto put_out_dir;
 
-               if (update_dent_inode(old_inode, &new_dentry->d_name)) {
+               if (update_dent_inode(old_inode, new_inode,
+                                               &new_dentry->d_name)) {
                        release_orphan_inode(sbi);
                        goto put_out_dir;
                }
@@ -557,6 +558,8 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        down_write(&F2FS_I(old_inode)->i_sem);
        file_lost_pino(old_inode);
+       if (new_inode && file_enc_name(new_inode))
+               file_set_enc_name(old_inode);
        up_write(&F2FS_I(old_inode)->i_sem);
 
        old_inode->i_ctime = CURRENT_TIME;
@@ -659,13 +662,17 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        f2fs_lock_op(sbi);
 
-       err = update_dent_inode(old_inode, &new_dentry->d_name);
+       err = update_dent_inode(old_inode, new_inode, &new_dentry->d_name);
        if (err)
                goto out_unlock;
+       if (file_enc_name(new_inode))
+               file_set_enc_name(old_inode);
 
-       err = update_dent_inode(new_inode, &old_dentry->d_name);
+       err = update_dent_inode(new_inode, old_inode, &old_dentry->d_name);
        if (err)
                goto out_undo;
+       if (file_enc_name(old_inode))
+               file_set_enc_name(new_inode);
 
        /* update ".." directory entry info of old dentry */
        if (old_dir_entry)
@@ -723,8 +730,11 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
                f2fs_sync_fs(sbi->sb, 1);
        return 0;
 out_undo:
-       /* Still we may fail to recover name info of f2fs_inode here */
-       update_dent_inode(old_inode, &old_dentry->d_name);
+       /*
+        * Still we may fail to recover name info of f2fs_inode here
+        * Drop it, once its name is set as encrypted
+        */
+       update_dent_inode(old_inode, old_inode, &old_dentry->d_name);
 out_unlock:
        f2fs_unlock_op(sbi);
 out_new_dir:
index f77a1beac78328abcd8e9cb61d188c31e27f8c4e..9de25878db2ba080d5cd0135d4af10beef650a01 100644 (file)
@@ -83,6 +83,11 @@ static int recover_dentry(struct inode *inode, struct page *ipage)
                goto out;
        }
 
+       if (file_enc_name(inode)) {
+               iput(dir);
+               return 0;
+       }
+
        name.len = le32_to_cpu(raw_inode->i_namelen);
        name.name = raw_inode->i_name;
 
@@ -143,6 +148,7 @@ out:
 static void recover_inode(struct inode *inode, struct page *page)
 {
        struct f2fs_inode *raw = F2FS_INODE(page);
+       char *name;
 
        inode->i_mode = le16_to_cpu(raw->i_mode);
        i_size_write(inode, le64_to_cpu(raw->i_size));
@@ -153,8 +159,13 @@ static void recover_inode(struct inode *inode, struct page *page)
        inode->i_ctime.tv_nsec = le32_to_cpu(raw->i_ctime_nsec);
        inode->i_mtime.tv_nsec = le32_to_cpu(raw->i_mtime_nsec);
 
+       if (file_enc_name(inode))
+               name = "<encrypted>";
+       else
+               name = F2FS_INODE(page)->i_name;
+
        f2fs_msg(inode->i_sb, KERN_NOTICE, "recover_inode: ino = %x, name = %s",
-                       ino_of_node(page), F2FS_INODE(page)->i_name);
+                       ino_of_node(page), name);
 }
 
 static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head)