Release 4.10 fs/ecryptfs/inode.c
/**
* eCryptfs: Linux filesystem encryption layer
*
* Copyright (C) 1997-2004 Erez Zadok
* Copyright (C) 2001-2004 Stony Brook University
* Copyright (C) 2004-2007 International Business Machines Corp.
* Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
* Michael C. Thompsion <mcthomps@us.ibm.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <linux/file.h>
#include <linux/vmalloc.h>
#include <linux/pagemap.h>
#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/fs_stack.h>
#include <linux/slab.h>
#include <linux/xattr.h>
#include <asm/unaligned.h>
#include "ecryptfs_kernel.h"
static struct dentry *lock_parent(struct dentry *dentry)
{
struct dentry *dir;
dir = dget_parent(dentry);
inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
return dir;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 31 | 81.58% | 1 | 20.00% |
david howells | david howells | 3 | 7.89% | 1 | 20.00% |
peter zijlstra | peter zijlstra | 2 | 5.26% | 1 | 20.00% |
al viro | al viro | 1 | 2.63% | 1 | 20.00% |
miklos szeredi | miklos szeredi | 1 | 2.63% | 1 | 20.00% |
| Total | 38 | 100.00% | 5 | 100.00% |
static void unlock_dir(struct dentry *dir)
{
inode_unlock(d_inode(dir));
dput(dir);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 20 | 83.33% | 1 | 33.33% |
david howells | david howells | 3 | 12.50% | 1 | 33.33% |
al viro | al viro | 1 | 4.17% | 1 | 33.33% |
| Total | 24 | 100.00% | 3 | 100.00% |
static int ecryptfs_inode_test(struct inode *inode, void *lower_inode)
{
return ecryptfs_inode_to_lower(inode) == lower_inode;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
tyler hicks | tyler hicks | 22 | 95.65% | 1 | 50.00% |
himangi saraogi | himangi saraogi | 1 | 4.35% | 1 | 50.00% |
| Total | 23 | 100.00% | 2 | 100.00% |
static int ecryptfs_inode_set(struct inode *inode, void *opaque)
{
struct inode *lower_inode = opaque;
ecryptfs_set_inode_lower(inode, lower_inode);
fsstack_copy_attr_all(inode, lower_inode);
/* i_size will be overwritten for encrypted regular files */
fsstack_copy_inode_size(inode, lower_inode);
inode->i_ino = lower_inode->i_ino;
inode->i_version++;
inode->i_mapping->a_ops = &ecryptfs_aops;
if (S_ISLNK(inode->i_mode))
inode->i_op = &ecryptfs_symlink_iops;
else if (S_ISDIR(inode->i_mode))
inode->i_op = &ecryptfs_dir_iops;
else
inode->i_op = &ecryptfs_main_iops;
if (S_ISDIR(inode->i_mode))
inode->i_fop = &ecryptfs_dir_fops;
else if (special_file(inode->i_mode))
init_special_inode(inode, inode->i_mode, inode->i_rdev);
else
inode->i_fop = &ecryptfs_main_fops;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
tyler hicks | tyler hicks | 157 | 100.00% | 2 | 100.00% |
| Total | 157 | 100.00% | 2 | 100.00% |
static struct inode *__ecryptfs_get_inode(struct inode *lower_inode,
struct super_block *sb)
{
struct inode *inode;
if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb))
return ERR_PTR(-EXDEV);
if (!igrab(lower_inode))
return ERR_PTR(-ESTALE);
inode = iget5_locked(sb, (unsigned long)lower_inode,
ecryptfs_inode_test, ecryptfs_inode_set,
lower_inode);
if (!inode) {
iput(lower_inode);
return ERR_PTR(-EACCES);
}
if (!(inode->i_state & I_NEW))
iput(lower_inode);
return inode;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
tyler hicks | tyler hicks | 113 | 100.00% | 2 | 100.00% |
| Total | 113 | 100.00% | 2 | 100.00% |
struct inode *ecryptfs_get_inode(struct inode *lower_inode,
struct super_block *sb)
{
struct inode *inode = __ecryptfs_get_inode(lower_inode, sb);
if (!IS_ERR(inode) && (inode->i_state & I_NEW))
unlock_new_inode(inode);
return inode;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
tyler hicks | tyler hicks | 53 | 100.00% | 2 | 100.00% |
| Total | 53 | 100.00% | 2 | 100.00% |
/**
* ecryptfs_interpose
* @lower_dentry: Existing dentry in the lower filesystem
* @dentry: ecryptfs' dentry
* @sb: ecryptfs's super_block
*
* Interposes upper and lower dentries.
*
* Returns zero on success; non-zero otherwise
*/
static int ecryptfs_interpose(struct dentry *lower_dentry,
struct dentry *dentry, struct super_block *sb)
{
struct inode *inode = ecryptfs_get_inode(d_inode(lower_dentry), sb);
if (IS_ERR(inode))
return PTR_ERR(inode);
d_instantiate(dentry, inode);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
tyler hicks | tyler hicks | 56 | 94.92% | 2 | 66.67% |
david howells | david howells | 3 | 5.08% | 1 | 33.33% |
| Total | 59 | 100.00% | 3 | 100.00% |
static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry,
struct inode *inode)
{
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
struct dentry *lower_dir_dentry;
int rc;
dget(lower_dentry);
lower_dir_dentry = lock_parent(lower_dentry);
rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL);
if (rc) {
printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
goto out_unlock;
}
fsstack_copy_attr_times(dir, lower_dir_inode);
set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink);
inode->i_ctime = dir->i_ctime;
d_drop(dentry);
out_unlock:
unlock_dir(lower_dir_dentry);
dput(lower_dentry);
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
tyler hicks | tyler hicks | 134 | 98.53% | 1 | 50.00% |
j. bruce fields | j. bruce fields | 2 | 1.47% | 1 | 50.00% |
| Total | 136 | 100.00% | 2 | 100.00% |
/**
* ecryptfs_do_create
* @directory_inode: inode of the new file's dentry's parent in ecryptfs
* @ecryptfs_dentry: New file's dentry in ecryptfs
* @mode: The mode of the new file
*
* Creates the underlying file and the eCryptfs inode which will link to
* it. It will also update the eCryptfs directory inode to mimic the
* stat of the lower directory inode.
*
* Returns the new eCryptfs inode on success; an ERR_PTR on error condition
*/
static struct inode *
ecryptfs_do_create(struct inode *directory_inode,
struct dentry *ecryptfs_dentry, umode_t mode)
{
int rc;
struct dentry *lower_dentry;
struct dentry *lower_dir_dentry;
struct inode *inode;
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
lower_dir_dentry = lock_parent(lower_dentry);
rc = vfs_create(d_inode(lower_dir_dentry), lower_dentry, mode, true);
if (rc) {
printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
"rc = [%d]\n", __func__, rc);
inode = ERR_PTR(rc);
goto out_lock;
}
inode = __ecryptfs_get_inode(d_inode(lower_dentry),
directory_inode->i_sb);
if (IS_ERR(inode)) {
vfs_unlink(d_inode(lower_dir_dentry), lower_dentry, NULL);
goto out_lock;
}
fsstack_copy_attr_times(directory_inode, d_inode(lower_dir_dentry));
fsstack_copy_inode_size(directory_inode, d_inode(lower_dir_dentry));
out_lock:
unlock_dir(lower_dir_dentry);
return inode;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 102 | 62.20% | 3 | 25.00% |
tyler hicks | tyler hicks | 31 | 18.90% | 2 | 16.67% |
david howells | david howells | 15 | 9.15% | 1 | 8.33% |
josef 'jeff' sipek | josef 'jeff' sipek | 8 | 4.88% | 1 | 8.33% |
al viro | al viro | 5 | 3.05% | 3 | 25.00% |
j. bruce fields | j. bruce fields | 2 | 1.22% | 1 | 8.33% |
harvey harrison | harvey harrison | 1 | 0.61% | 1 | 8.33% |
| Total | 164 | 100.00% | 12 | 100.00% |
/**
* ecryptfs_initialize_file
*
* Cause the file to be changed from a basic empty file to an ecryptfs
* file with a header and first data page.
*
* Returns zero on success
*/
int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
struct inode *ecryptfs_inode)
{
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
int rc = 0;
if (S_ISDIR(ecryptfs_inode->i_mode)) {
ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
goto out;
}
ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
rc = ecryptfs_new_file_context(ecryptfs_inode);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error creating new file "
"context; rc = [%d]\n", rc);
goto out;
}
rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode);
if (rc) {
printk(KERN_ERR "%s: Error attempting to initialize "
"the lower file for the dentry with name "
"[%pd]; rc = [%d]\n", __func__,
ecryptfs_dentry, rc);
goto out;
}
rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode);
if (rc)
printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
ecryptfs_put_lower_file(ecryptfs_inode);
out:
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 139 | 87.42% | 5 | 55.56% |
tyler hicks | tyler hicks | 19 | 11.95% | 3 | 33.33% |
david howells | david howells | 1 | 0.63% | 1 | 11.11% |
| Total | 159 | 100.00% | 9 | 100.00% |
/**
* ecryptfs_create
* @dir: The inode of the directory in which to create the file.
* @dentry: The eCryptfs dentry
* @mode: The mode of the new file.
*
* Creates a new file.
*
* Returns zero on success; non-zero on error condition
*/
static int
ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
umode_t mode, bool excl)
{
struct inode *ecryptfs_inode;
int rc;
ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry,
mode);
if (IS_ERR(ecryptfs_inode)) {
ecryptfs_printk(KERN_WARNING, "Failed to create file in"
"lower filesystem\n");
rc = PTR_ERR(ecryptfs_inode);
goto out;
}
/* At this point, a file exists on "disk"; we need to make sure
* that this on disk file is prepared to be an ecryptfs file */
rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode);
if (rc) {
ecryptfs_do_unlink(directory_inode, ecryptfs_dentry,
ecryptfs_inode);
iget_failed(ecryptfs_inode);
goto out;
}
unlock_new_inode(ecryptfs_inode);
d_instantiate(ecryptfs_dentry, ecryptfs_inode);
out:
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 61 | 51.69% | 1 | 14.29% |
tyler hicks | tyler hicks | 49 | 41.53% | 2 | 28.57% |
al viro | al viro | 8 | 6.78% | 4 | 57.14% |
| Total | 118 | 100.00% | 7 | 100.00% |
static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode)
{
struct ecryptfs_crypt_stat *crypt_stat;
int rc;
rc = ecryptfs_get_lower_file(dentry, inode);
if (rc) {
printk(KERN_ERR "%s: Error attempting to initialize "
"the lower file for the dentry with name "
"[%pd]; rc = [%d]\n", __func__,
dentry, rc);
return rc;
}
crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
/* TODO: lock for crypt_stat comparison */
if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED))
ecryptfs_set_default_sizes(crypt_stat);
rc = ecryptfs_read_and_validate_header_region(inode);
ecryptfs_put_lower_file(inode);
if (rc) {
rc = ecryptfs_read_and_validate_xattr_region(dentry, inode);
if (!rc)
crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR;
}
/* Must return 0 to allow non-eCryptfs files to be looked up, too */
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
tyler hicks | tyler hicks | 124 | 99.20% | 1 | 50.00% |
david howells | david howells | 1 | 0.80% | 1 | 50.00% |
| Total | 125 | 100.00% | 2 | 100.00% |
/**
* ecryptfs_lookup_interpose - Dentry interposition for a lookup
*/
static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry,
struct dentry *lower_dentry)
{
struct inode *inode, *lower_inode = d_inode(lower_dentry);
struct ecryptfs_dentry_info *dentry_info;
struct vfsmount *lower_mnt;
int rc = 0;
dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL);
if (!dentry_info) {
printk(KERN_ERR "%s: Out of memory whilst attempting "
"to allocate ecryptfs_dentry_info struct\n",
__func__);
dput(lower_dentry);
return ERR_PTR(-ENOMEM);
}
lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent));
fsstack_copy_attr_atime(d_inode(dentry->d_parent),
d_inode(lower_dentry->d_parent));
BUG_ON(!d_count(lower_dentry));
ecryptfs_set_dentry_private(dentry, dentry_info);
dentry_info->lower_path.mnt = lower_mnt;
dentry_info->lower_path.dentry = lower_dentry;
if (d_really_is_negative(lower_dentry)) {
/* We want to add because we couldn't find in lower */
d_add(dentry, NULL);
return NULL;
}
inode = __ecryptfs_get_inode(lower_inode, dentry->d_sb);
if (IS_ERR(inode)) {
printk(KERN_ERR "%s: Error interposing; rc = [%ld]\n",
__func__, PTR_ERR(inode));
return ERR_CAST(inode);
}
if (S_ISREG(inode->i_mode)) {
rc = ecryptfs_i_size_read(dentry, inode);
if (rc) {
make_bad_inode(inode);
return ERR_PTR(rc);
}
}
if (inode->i_state & I_NEW)
unlock_new_inode(inode);
return d_splice_alias(inode, dentry);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 101 | 38.70% | 6 | 35.29% |
tyler hicks | tyler hicks | 77 | 29.50% | 5 | 29.41% |
al viro | al viro | 73 | 27.97% | 4 | 23.53% |
david howells | david howells | 9 | 3.45% | 1 | 5.88% |
josef 'jeff' sipek | josef 'jeff' sipek | 1 | 0.38% | 1 | 5.88% |
| Total | 261 | 100.00% | 17 | 100.00% |
/**
* ecryptfs_lookup
* @ecryptfs_dir_inode: The eCryptfs directory inode
* @ecryptfs_dentry: The eCryptfs dentry that we are looking up
* @flags: lookup flags
*
* Find a file on disk. If the file does not exist, then we'll add it to the
* dentry cache and continue on to read it from the disk.
*/
static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
struct dentry *ecryptfs_dentry,
unsigned int flags)
{
char *encrypted_and_encoded_name = NULL;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
struct dentry *lower_dir_dentry, *lower_dentry;
const char *name = ecryptfs_dentry->d_name.name;
size_t len = ecryptfs_dentry->d_name.len;
struct dentry *res;
int rc = 0;
lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent);
mount_crypt_stat = &ecryptfs_superblock_to_private(
ecryptfs_dentry->d_sb)->mount_crypt_stat;
if (mount_crypt_stat
&& (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) {
rc = ecryptfs_encrypt_and_encode_filename(
&encrypted_and_encoded_name, &len,
mount_crypt_stat, name, len);
if (rc) {
printk(KERN_ERR "%s: Error attempting to encrypt and encode "
"filename; rc = [%d]\n", __func__, rc);
return ERR_PTR(rc);
}
name = encrypted_and_encoded_name;
}
lower_dentry = lookup_one_len_unlocked(name, lower_dir_dentry, len);
if (IS_ERR(lower_dentry)) {
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
"[%ld] on lower_dentry = [%s]\n", __func__,
PTR_ERR(lower_dentry),
name);
res = ERR_CAST(lower_dentry);
} else {
res = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry);
}
kfree(encrypted_and_encoded_name);
return res;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 146 | 68.22% | 3 | 25.00% |
al viro | al viro | 50 | 23.36% | 5 | 41.67% |
tyler hicks | tyler hicks | 18 | 8.41% | 4 | 33.33% |
| Total | 214 | 100.00% | 12 | 100.00% |
static int ecryptfs_link(struct dentry *old_dentry, struct inode *dir,
struct dentry *new_dentry)
{
struct dentry *lower_old_dentry;
struct dentry *lower_new_dentry;
struct dentry *lower_dir_dentry;
u64 file_size_save;
int rc;
file_size_save = i_size_read(d_inode(old_dentry));
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
dget(lower_old_dentry);
dget(lower_new_dentry);
lower_dir_dentry = lock_parent(lower_new_dentry);
rc = vfs_link(lower_old_dentry, d_inode(lower_dir_dentry),
lower_new_dentry, NULL);
if (rc || d_really_is_negative(lower_new_dentry))
goto out_lock;
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
if (rc)
goto out_lock;
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
set_nlink(d_inode(old_dentry),
ecryptfs_inode_to_lower(d_inode(old_dentry))->i_nlink);
i_size_write(d_inode(new_dentry), file_size_save);
out_lock:
unlock_dir(lower_dir_dentry);
dput(lower_new_dentry);
dput(lower_old_dentry);
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 161 | 80.90% | 1 | 20.00% |
david howells | david howells | 24 | 12.06% | 1 | 20.00% |
josef 'jeff' sipek | josef 'jeff' sipek | 8 | 4.02% | 1 | 20.00% |
miklos szeredi | miklos szeredi | 4 | 2.01% | 1 | 20.00% |
j. bruce fields | j. bruce fields | 2 | 1.01% | 1 | 20.00% |
| Total | 199 | 100.00% | 5 | 100.00% |
static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry)
{
return ecryptfs_do_unlink(dir, dentry, d_inode(dentry));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 23 | 79.31% | 1 | 25.00% |
david howells | david howells | 3 | 10.34% | 1 | 25.00% |
tyler hicks | tyler hicks | 2 | 6.90% | 1 | 25.00% |
miklos szeredi | miklos szeredi | 1 | 3.45% | 1 | 25.00% |
| Total | 29 | 100.00% | 4 | 100.00% |
static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
const char *symname)
{
int rc;
struct dentry *lower_dentry;
struct dentry *lower_dir_dentry;
char *encoded_symname;
size_t encoded_symlen;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL;
lower_dentry = ecryptfs_dentry_to_lower(dentry);
dget(lower_dentry);
lower_dir_dentry = lock_parent(lower_dentry);
mount_crypt_stat = &ecryptfs_superblock_to_private(
dir->i_sb)->mount_crypt_stat;
rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname,
&encoded_symlen,
mount_crypt_stat, symname,
strlen(symname));
if (rc)
goto out_lock;
rc = vfs_symlink(d_inode(lower_dir_dentry), lower_dentry,
encoded_symname);
kfree(encoded_symname);
if (rc || d_really_is_negative(lower_dentry))
goto out_lock;
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
if (rc)
goto out_lock;
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
out_lock:
unlock_dir(lower_dir_dentry);
dput(lower_dentry);
if (d_really_is_negative(dentry))
d_drop(dentry);
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 181 | 88.73% | 2 | 50.00% |
david howells | david howells | 15 | 7.35% | 1 | 25.00% |
josef 'jeff' sipek | josef 'jeff' sipek | 8 | 3.92% | 1 | 25.00% |
| Total | 204 | 100.00% | 4 | 100.00% |
static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
int rc;
struct dentry *lower_dentry;
struct dentry *lower_dir_dentry;
lower_dentry = ecryptfs_dentry_to_lower(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
rc = vfs_mkdir(d_inode(lower_dir_dentry), lower_dentry, mode);
if (rc || d_really_is_negative(lower_dentry))
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
if (rc)
goto out;
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink);
out:
unlock_dir(lower_dir_dentry);
if (d_really_is_negative(dentry))
d_drop(dentry);
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 115 | 78.77% | 1 | 20.00% |
david howells | david howells | 18 | 12.33% | 1 | 20.00% |
josef 'jeff' sipek | josef 'jeff' sipek | 8 | 5.48% | 1 | 20.00% |
miklos szeredi | miklos szeredi | 4 | 2.74% | 1 | 20.00% |
al viro | al viro | 1 | 0.68% | 1 | 20.00% |
| Total | 146 | 100.00% | 5 | 100.00% |
static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
{
struct dentry *lower_dentry;
struct dentry *lower_dir_dentry;
int rc;
lower_dentry = ecryptfs_dentry_to_lower(dentry);
dget(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
dget(lower_dentry);
rc = vfs_rmdir(d_inode(lower_dir_dentry), lower_dentry);
dput(lower_dentry);
if (!rc && d_really_is_positive(dentry))
clear_nlink(d_inode(dentry));
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink);
unlock_dir(lower_dir_dentry);
if (!rc)
d_drop(dentry);
dput(dentry);
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 101 | 75.94% | 2 | 33.33% |
david howells | david howells | 15 | 11.28% | 1 | 16.67% |
tyler hicks | tyler hicks | 12 | 9.02% | 1 | 16.67% |
miklos szeredi | miklos szeredi | 4 | 3.01% | 1 | 16.67% |
josef 'jeff' sipek | josef 'jeff' sipek | 1 | 0.75% | 1 | 16.67% |
| Total | 133 | 100.00% | 6 | 100.00% |
static int
ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
{
int rc;
struct dentry *lower_dentry;
struct dentry *lower_dir_dentry;
lower_dentry = ecryptfs_dentry_to_lower(dentry);
lower_dir_dentry = lock_parent(lower_dentry);
rc = vfs_mknod(d_inode(lower_dir_dentry), lower_dentry, mode, dev);
if (rc || d_really_is_negative(lower_dentry))
goto out;
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
if (rc)
goto out;
fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry));
fsstack_copy_inode_size(dir, d_inode(lower_dir_dentry));
out:
unlock_dir(lower_dir_dentry);
if (d_really_is_negative(dentry))
d_drop(dentry);
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 115 | 82.73% | 1 | 25.00% |
david howells | david howells | 15 | 10.79% | 1 | 25.00% |
josef 'jeff' sipek | josef 'jeff' sipek | 8 | 5.76% | 1 | 25.00% |
al viro | al viro | 1 | 0.72% | 1 | 25.00% |
| Total | 139 | 100.00% | 4 | 100.00% |
static int
ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags)
{
int rc;
struct dentry *lower_old_dentry;
struct dentry *lower_new_dentry;
struct dentry *lower_old_dir_dentry;
struct dentry *lower_new_dir_dentry;
struct dentry *trap = NULL;
struct inode *target_inode;
if (flags)
return -EINVAL;
lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry);
lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
dget(lower_old_dentry);
dget(lower_new_dentry);
lower_old_dir_dentry = dget_parent(lower_old_dentry);
lower_new_dir_dentry = dget_parent(lower_new_dentry);
target_inode = d_inode(new_dentry);
trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
/* source should not be ancestor of target */
if (trap == lower_old_dentry) {
rc = -EINVAL;
goto out_lock;
}
/* target should not be ancestor of source */
if (trap == lower_new_dentry) {
rc = -ENOTEMPTY;
goto out_lock;
}
rc = vfs_rename(d_inode(lower_old_dir_dentry), lower_old_dentry,
d_inode(lower_new_dir_dentry), lower_new_dentry,
NULL, 0);
if (rc)
goto out_lock;
if (target_inode)
fsstack_copy_attr_all(target_inode,
ecryptfs_inode_to_lower(target_inode));
fsstack_copy_attr_all(new_dir, d_inode(lower_new_dir_dentry));
if (new_dir != old_dir)
fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry));
out_lock:
unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
dput(lower_new_dir_dentry);
dput(lower_old_dir_dentry);
dput(lower_new_dentry);
dput(lower_old_dentry);
return rc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
michael halcrow | michael halcrow | 162 | 61.60% | 2 | 20.00% |
erez zadok | erez zadok | 43 | 16.35% | 1 | 10.00% |
tyler hicks | tyler hicks | 25 | 9.51% | 2 | 20.00% |
david howells | david howells | 15 | 5.70% | 1 | 10.00% |
miklos szeredi | miklos szeredi | 14 | 5.32% | 2 | 20.00% |
j. bruce fields | j. bruce fields | 2 | 0.76% | 1 | 10.00% |
josef 'jeff' sipek | josef 'jeff' sipek | 2 | 0.76% | 1 | 10.00% |
| Total | 263 | 100.00% | 10 | 100.00% |
static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz)
{
DEFINE_DELAYED_CALL(done);
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
const char *link;
char *buf;
int rc;
link = vfs_get_link(lower_dentry, &done);
if (IS_ERR(link))
return ERR_CAST(link);
rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb,
link, strlen(link)