Whamcloud - gitweb
LU-13717 sec: filename encryption
[fs/lustre-release.git] / lustre / llite / namei.c
index 6b56934..951619f 100644 (file)
@@ -822,6 +822,7 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
        __u32 opc;
        int rc;
        char secctx_name[XATTR_NAME_MAX + 1];
+       struct llcrypt_name fname;
 
        ENTRY;
 
@@ -850,12 +851,32 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
        if (it->it_op & IT_CREAT)
                opc = LUSTRE_OPC_CREATE;
        else
-               opc = LUSTRE_OPC_ANY;
+               opc = LUSTRE_OPC_LOOKUP;
+
+       /* Here we should be calling llcrypt_prepare_lookup(). But it installs a
+        * custom ->d_revalidate() method, so we lose ll_d_ops.
+        * To workaround this, call ll_setup_filename() and do the rest
+        * manually. Also make a copy of llcrypt_d_revalidate() (unfortunately
+        * not exported function) and call it from ll_revalidate_dentry(), to
+        * ensure we do not cache stale dentries after a key has been added.
+        */
+       rc = ll_setup_filename(parent, &dentry->d_name, 1, &fname);
+       if ((!rc || rc == -ENOENT) && fname.is_ciphertext_name) {
+               spin_lock(&dentry->d_lock);
+               dentry->d_flags |= DCACHE_ENCRYPTED_NAME;
+               spin_unlock(&dentry->d_lock);
+       }
+       if (rc == -ENOENT)
+               RETURN(NULL);
+       if (rc)
+               RETURN(ERR_PTR(rc));
 
-       op_data = ll_prep_md_op_data(NULL, parent, NULL, dentry->d_name.name,
-                                    dentry->d_name.len, 0, opc, NULL);
-       if (IS_ERR(op_data))
-               GOTO(out, retval = ERR_CAST(op_data));
+       op_data = ll_prep_md_op_data(NULL, parent, NULL, fname.disk_name.name,
+                                    fname.disk_name.len, 0, opc, NULL);
+       if (IS_ERR(op_data)) {
+               llcrypt_free_filename(&fname);
+               RETURN(ERR_CAST(op_data));
+       }
 
        /* enforce umask if acl disabled or MDS doesn't support umask */
        if (!IS_POSIXACL(parent) || !exp_connect_umask(ll_i2mdexp(parent)))
@@ -1083,6 +1104,7 @@ out:
                        op_data->op_file_encctx = NULL;
                        op_data->op_file_encctx_size = 0;
                }
+               llcrypt_free_filename(&fname);
                ll_finish_md_op_data(op_data);
        }
 
@@ -1983,13 +2005,12 @@ static int ll_rename(struct inode *src, struct dentry *src_dchild,
 #endif
                     )
 {
-       struct qstr *src_name = &src_dchild->d_name;
-       struct qstr *tgt_name = &tgt_dchild->d_name;
        struct ptlrpc_request *request = NULL;
        struct ll_sb_info *sbi = ll_i2sbi(src);
        struct md_op_data *op_data;
        ktime_t kstart = ktime_get();
        umode_t mode = 0;
+       struct llcrypt_name foldname, fnewname;
        int err;
        ENTRY;
 
@@ -2036,9 +2057,20 @@ static int ll_rename(struct inode *src, struct dentry *src_dchild,
        if (tgt_dchild->d_inode)
                op_data->op_fid4 = *ll_inode2fid(tgt_dchild->d_inode);
 
+       err = ll_setup_filename(src, &src_dchild->d_name, 1, &foldname);
+       if (err)
+               RETURN(err);
+       err = ll_setup_filename(tgt, &tgt_dchild->d_name, 1, &fnewname);
+       if (err) {
+               llcrypt_free_filename(&foldname);
+               RETURN(err);
+       }
        err = md_rename(sbi->ll_md_exp, op_data,
-                       src_name->name, src_name->len,
-                       tgt_name->name, tgt_name->len, &request);
+                       foldname.disk_name.name, foldname.disk_name.len,
+                       fnewname.disk_name.name, fnewname.disk_name.len,
+                       &request);
+       llcrypt_free_filename(&foldname);
+       llcrypt_free_filename(&fnewname);
        ll_finish_md_op_data(op_data);
        if (!err) {
                ll_update_times(request, src);