Clean up whitespace and fixed a bug in the context inheritance error path
[ext4-patch-queue.git] / partial-update-to-namei.c-for-fname-crypto
blob44baf901238cacc3ebdb300d824b6a994c42927e
1 ext4 crypto: partial update to namei.c for fname crypto
3 From: Michael Halcrow <mhalcrow@google.com>
5 Modifies dx_show_leaf and dx_probe to support fname encryption.
6 Filename encryption not yet enabled.
8 Signed-off-by: Uday Savagaonkar <savagaon@google.com>
9 Signed-off-by: Ildar Muslukhov <ildarm@google.com>
10 Signed-off-by: Michael Halcrow <mhalcrow@google.com>
11 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
12 ---
13  fs/ext4/namei.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
14  1 file changed, 101 insertions(+), 8 deletions(-)
16 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
17 index f3234d4..8fcda60 100644
18 --- a/fs/ext4/namei.c
19 +++ b/fs/ext4/namei.c
20 @@ -588,8 +588,10 @@ struct stats
21         unsigned bcount;
22  };
24 -static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext4_dir_entry_2 *de,
25 -                                int size, int show_names)
26 +static struct stats dx_show_leaf(struct inode *dir,
27 +                               struct dx_hash_info *hinfo,
28 +                               struct ext4_dir_entry_2 *de,
29 +                               int size, int show_names)
30  {
31         unsigned names = 0, space = 0;
32         char *base = (char *) de;
33 @@ -602,12 +604,80 @@ static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext4_dir_ent
34                 {
35                         if (show_names)
36                         {
37 +#ifdef CONFIG_EXT4_FS_ENCRYPTION
38 +                               int len;
39 +                               char *name;
40 +                               struct ext4_str fname_crypto_str
41 +                                       = {.name = NULL, .len = 0};
42 +                               struct ext4_fname_crypto_ctx *ctx = NULL;
43 +                               int res;
45 +                               name  = de->name;
46 +                               len = de->name_len;
47 +                               ctx = ext4_get_fname_crypto_ctx(dir,
48 +                                                               EXT4_NAME_LEN);
49 +                               if (IS_ERR(ctx)) {
50 +                                       printk(KERN_WARNING "Error acquiring"
51 +                                       " crypto ctxt--skipping crypto\n");
52 +                                       ctx = NULL;
53 +                               }
54 +                               if (ctx == NULL) {
55 +                                       /* Directory is not encrypted */
56 +                                       ext4fs_dirhash(de->name,
57 +                                               de->name_len, &h);
58 +                                       printk("%*.s:(U)%x.%u ", len,
59 +                                              name, h.hash,
60 +                                              (unsigned) ((char *) de
61 +                                                          - base));
62 +                               } else {
63 +                                       /* Directory is encrypted */
64 +                                       res = ext4_fname_crypto_alloc_buffer(
65 +                                               ctx, de->name_len,
66 +                                               &fname_crypto_str);
67 +                                       if (res < 0) {
68 +                                               printk(KERN_WARNING "Error "
69 +                                                       "allocating crypto "
70 +                                                       "buffer--skipping "
71 +                                                       "crypto\n");
72 +                                               ext4_put_fname_crypto_ctx(&ctx);
73 +                                               ctx = NULL;
74 +                                       }
75 +                                       res = ext4_fname_disk_to_usr(ctx, de,
76 +                                                       &fname_crypto_str);
77 +                                       if (res < 0) {
78 +                                               printk(KERN_WARNING "Error "
79 +                                                       "converting filename "
80 +                                                       "from disk to usr"
81 +                                                       "\n");
82 +                                               name = "??";
83 +                                               len = 2;
84 +                                       } else {
85 +                                               name = fname_crypto_str.name;
86 +                                               len = fname_crypto_str.len;
87 +                                       }
88 +                                       res = ext4_fname_disk_to_hash(ctx, de,
89 +                                                                     &h);
90 +                                       if (res < 0) {
91 +                                               printk(KERN_WARNING "Error "
92 +                                                       "converting filename "
93 +                                                       "from disk to htree"
94 +                                                       "\n");
95 +                                               h.hash = 0xDEADBEEF;
96 +                                       }
97 +                                       printk("%*.s:(E)%x.%u ", len, name,
98 +                                              h.hash, (unsigned) ((char *) de
99 +                                                                  - base));
100 +                                       ext4_put_fname_crypto_ctx(&ctx);
101 +                                       ext4_fname_crypto_free_buffer(
102 +                                               &fname_crypto_str);
103 +                               }
104 +#else
105                                 int len = de->name_len;
106                                 char *name = de->name;
107 -                               while (len--) printk("%c", *name++);
108                                 ext4fs_dirhash(de->name, de->name_len, &h);
109 -                               printk(":%x.%u ", h.hash,
110 +                               printk("%*.s:%x.%u ", len, name, h.hash,
111                                        (unsigned) ((char *) de - base));
112 +#endif
113                         }
114                         space += EXT4_DIR_REC_LEN(de->name_len);
115                         names++;
116 @@ -625,7 +695,6 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
117         unsigned count = dx_get_count(entries), names = 0, space = 0, i;
118         unsigned bcount = 0;
119         struct buffer_head *bh;
120 -       int err;
121         printk("%i indexed blocks...\n", count);
122         for (i = 0; i < count; i++, entries++)
123         {
124 @@ -639,7 +708,8 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
125                         continue;
126                 stats = levels?
127                    dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
128 -                  dx_show_leaf(hinfo, (struct ext4_dir_entry_2 *) bh->b_data, blocksize, 0);
129 +                  dx_show_leaf(dir, hinfo, (struct ext4_dir_entry_2 *)
130 +                       bh->b_data, blocksize, 0);
131                 names += stats.names;
132                 space += stats.space;
133                 bcount += stats.bcount;
134 @@ -689,8 +759,28 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
135         if (hinfo->hash_version <= DX_HASH_TEA)
136                 hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
137         hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
138 +#ifdef CONFIG_EXT4_FS_ENCRYPTION
139 +       if (d_name) {
140 +               struct ext4_fname_crypto_ctx *ctx = NULL;
141 +               int res;
143 +               /* Check if the directory is encrypted */
144 +               ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
145 +               if (IS_ERR(ctx)) {
146 +                       ret_err = ERR_PTR(PTR_ERR(ctx));
147 +                       goto fail;
148 +               }
149 +               res = ext4_fname_usr_to_hash(ctx, d_name, hinfo);
150 +               if (res < 0) {
151 +                       ret_err = ERR_PTR(res);
152 +                       goto fail;
153 +               }
154 +               ext4_put_fname_crypto_ctx(&ctx);
155 +       }
156 +#else
157         if (d_name)
158                 ext4fs_dirhash(d_name->name, d_name->len, hinfo);
159 +#endif
160         hash = hinfo->hash;
162         if (root->info.unused_flags & 1) {
163 @@ -775,6 +865,7 @@ fail:
164                 brelse(frame->bh);
165                 frame--;
166         }
168         if (ret_err == ERR_PTR(ERR_BAD_DX_DIR))
169                 ext4_warning(dir->i_sb,
170                              "Corrupt dir inode %lu, running e2fsck is "
171 @@ -1602,8 +1693,10 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
172                 initialize_dirent_tail(t, blocksize);
173         }
175 -       dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data1, blocksize, 1));
176 -       dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data2, blocksize, 1));
177 +       dxtrace(dx_show_leaf(dir, hinfo, (struct ext4_dir_entry_2 *) data1,
178 +                       blocksize, 1));
179 +       dxtrace(dx_show_leaf(dir, hinfo, (struct ext4_dir_entry_2 *) data2,
180 +                       blocksize, 1));
182         /* Which block gets the new entry? */
183         if (hinfo->hash >= hash2) {