Blame view
fs/ecryptfs/inode.c
32.9 KB
237fead61 [PATCH] ecryptfs:... |
1 2 3 4 5 |
/** * eCryptfs: Linux filesystem encryption layer * * Copyright (C) 1997-2004 Erez Zadok * Copyright (C) 2001-2004 Stony Brook University |
dd2a3b7ad [PATCH] eCryptfs:... |
6 |
* Copyright (C) 2004-2007 International Business Machines Corp. |
237fead61 [PATCH] ecryptfs:... |
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
* 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/crypto.h> |
0cc72dc7f [PATCH] eCryptfs:... |
33 |
#include <linux/fs_stack.h> |
5a0e3ad6a include cleanup: ... |
34 |
#include <linux/slab.h> |
48b512e68 ecryptfs: call vf... |
35 |
#include <linux/xattr.h> |
0a688ad71 ecryptfs: inode.c... |
36 |
#include <asm/unaligned.h> |
237fead61 [PATCH] ecryptfs:... |
37 38 39 40 41 |
#include "ecryptfs_kernel.h" static struct dentry *lock_parent(struct dentry *dentry) { struct dentry *dir; |
8dc4e3736 ecryptfs: clean u... |
42 |
dir = dget_parent(dentry); |
908e0a8a2 [PATCH] ecryptfs:... |
43 |
mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT); |
237fead61 [PATCH] ecryptfs:... |
44 45 |
return dir; } |
237fead61 [PATCH] ecryptfs:... |
46 47 48 49 50 |
static void unlock_dir(struct dentry *dir) { mutex_unlock(&dir->d_inode->i_mutex); dput(dir); } |
c4f790736 eCryptfs: Consoli... |
51 52 53 54 55 56 |
static int ecryptfs_inode_test(struct inode *inode, void *lower_inode) { if (ecryptfs_inode_to_lower(inode) == (struct inode *)lower_inode) return 1; return 0; } |
5ccf92037 eCryptfs: Cleanup... |
57 |
static int ecryptfs_inode_set(struct inode *inode, void *opaque) |
c4f790736 eCryptfs: Consoli... |
58 |
{ |
5ccf92037 eCryptfs: Cleanup... |
59 60 61 62 63 64 65 |
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; |
c4f790736 eCryptfs: Consoli... |
66 |
inode->i_version++; |
c4f790736 eCryptfs: Consoli... |
67 |
inode->i_mapping->a_ops = &ecryptfs_aops; |
985ca0e62 ecryptfs: Make in... |
68 |
inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi; |
5ccf92037 eCryptfs: Cleanup... |
69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
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; |
c4f790736 eCryptfs: Consoli... |
83 84 |
return 0; } |
5ccf92037 eCryptfs: Cleanup... |
85 86 |
static struct inode *__ecryptfs_get_inode(struct inode *lower_inode, struct super_block *sb) |
c4f790736 eCryptfs: Consoli... |
87 88 |
{ struct inode *inode; |
c4f790736 eCryptfs: Consoli... |
89 |
|
5ccf92037 eCryptfs: Cleanup... |
90 91 92 93 |
if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) return ERR_PTR(-EXDEV); if (!igrab(lower_inode)) return ERR_PTR(-ESTALE); |
c4f790736 eCryptfs: Consoli... |
94 95 96 97 |
inode = iget5_locked(sb, (unsigned long)lower_inode, ecryptfs_inode_test, ecryptfs_inode_set, lower_inode); if (!inode) { |
c4f790736 eCryptfs: Consoli... |
98 |
iput(lower_inode); |
5ccf92037 eCryptfs: Cleanup... |
99 |
return ERR_PTR(-EACCES); |
c4f790736 eCryptfs: Consoli... |
100 |
} |
5ccf92037 eCryptfs: Cleanup... |
101 |
if (!(inode->i_state & I_NEW)) |
c4f790736 eCryptfs: Consoli... |
102 |
iput(lower_inode); |
5ccf92037 eCryptfs: Cleanup... |
103 104 105 106 107 108 109 110 111 112 113 |
return inode; } 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); |
c4f790736 eCryptfs: Consoli... |
114 |
return inode; |
c4f790736 eCryptfs: Consoli... |
115 |
} |
c4f790736 eCryptfs: Consoli... |
116 117 118 119 120 |
/** * ecryptfs_interpose * @lower_dentry: Existing dentry in the lower filesystem * @dentry: ecryptfs' dentry * @sb: ecryptfs's super_block |
c4f790736 eCryptfs: Consoli... |
121 122 123 124 125 126 |
* * Interposes upper and lower dentries. * * Returns zero on success; non-zero otherwise */ static int ecryptfs_interpose(struct dentry *lower_dentry, |
5ccf92037 eCryptfs: Cleanup... |
127 |
struct dentry *dentry, struct super_block *sb) |
c4f790736 eCryptfs: Consoli... |
128 |
{ |
5ccf92037 eCryptfs: Cleanup... |
129 |
struct inode *inode = ecryptfs_get_inode(lower_dentry->d_inode, sb); |
c4f790736 eCryptfs: Consoli... |
130 131 |
if (IS_ERR(inode)) return PTR_ERR(inode); |
5ccf92037 eCryptfs: Cleanup... |
132 |
d_instantiate(dentry, inode); |
c4f790736 eCryptfs: Consoli... |
133 134 |
return 0; } |
237fead61 [PATCH] ecryptfs:... |
135 |
/** |
237fead61 [PATCH] ecryptfs:... |
136 137 138 139 140 141 142 143 144 145 |
* 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 * @nd: nameidata of ecryptfs' parent's dentry & vfsmount * * 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. * |
b59db43ad eCryptfs: Prevent... |
146 |
* Returns the new eCryptfs inode on success; an ERR_PTR on error condition |
237fead61 [PATCH] ecryptfs:... |
147 |
*/ |
b59db43ad eCryptfs: Prevent... |
148 |
static struct inode * |
237fead61 [PATCH] ecryptfs:... |
149 |
ecryptfs_do_create(struct inode *directory_inode, |
175a4eb7e fs: propagate umo... |
150 |
struct dentry *ecryptfs_dentry, umode_t mode) |
237fead61 [PATCH] ecryptfs:... |
151 152 153 154 |
{ int rc; struct dentry *lower_dentry; struct dentry *lower_dir_dentry; |
b59db43ad eCryptfs: Prevent... |
155 |
struct inode *inode; |
237fead61 [PATCH] ecryptfs:... |
156 157 158 |
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); lower_dir_dentry = lock_parent(lower_dentry); |
801678c5a Remove duplicated... |
159 |
if (IS_ERR(lower_dir_dentry)) { |
237fead61 [PATCH] ecryptfs:... |
160 161 162 |
ecryptfs_printk(KERN_ERR, "Error locking directory of " "dentry "); |
b59db43ad eCryptfs: Prevent... |
163 |
inode = ERR_CAST(lower_dir_dentry); |
237fead61 [PATCH] ecryptfs:... |
164 165 |
goto out; } |
18cb1b08d kill ecryptfs_cre... |
166 |
rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, NULL); |
4981e081c eCryptfs: set up ... |
167 |
if (rc) { |
caeeeecfd eCryptfs: fix den... |
168 |
printk(KERN_ERR "%s: Failure to create dentry in lower fs; " |
18d1dbf1d ecryptfs: replace... |
169 170 |
"rc = [%d] ", __func__, rc); |
b59db43ad eCryptfs: Prevent... |
171 |
inode = ERR_PTR(rc); |
caeeeecfd eCryptfs: fix den... |
172 |
goto out_lock; |
237fead61 [PATCH] ecryptfs:... |
173 |
} |
b59db43ad eCryptfs: Prevent... |
174 175 176 |
inode = __ecryptfs_get_inode(lower_dentry->d_inode, directory_inode->i_sb); if (IS_ERR(inode)) |
237fead61 [PATCH] ecryptfs:... |
177 |
goto out_lock; |
0cc72dc7f [PATCH] eCryptfs:... |
178 179 |
fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); |
237fead61 [PATCH] ecryptfs:... |
180 181 182 |
out_lock: unlock_dir(lower_dir_dentry); out: |
b59db43ad eCryptfs: Prevent... |
183 |
return inode; |
237fead61 [PATCH] ecryptfs:... |
184 185 186 |
} /** |
237fead61 [PATCH] ecryptfs:... |
187 188 189 190 191 192 193 |
* 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 */ |
b59db43ad eCryptfs: Prevent... |
194 195 |
static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, struct inode *ecryptfs_inode) |
237fead61 [PATCH] ecryptfs:... |
196 |
{ |
d7cdc5feb eCryptfs: update ... |
197 |
struct ecryptfs_crypt_stat *crypt_stat = |
b59db43ad eCryptfs: Prevent... |
198 |
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
237fead61 [PATCH] ecryptfs:... |
199 |
int rc = 0; |
237fead61 [PATCH] ecryptfs:... |
200 |
|
b59db43ad eCryptfs: Prevent... |
201 |
if (S_ISDIR(ecryptfs_inode->i_mode)) { |
237fead61 [PATCH] ecryptfs:... |
202 203 |
ecryptfs_printk(KERN_DEBUG, "This is a directory "); |
e2bd99ec5 [PATCH] eCryptfs:... |
204 |
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
d7cdc5feb eCryptfs: update ... |
205 |
goto out; |
237fead61 [PATCH] ecryptfs:... |
206 |
} |
237fead61 [PATCH] ecryptfs:... |
207 208 |
ecryptfs_printk(KERN_DEBUG, "Initializing crypto context "); |
b59db43ad eCryptfs: Prevent... |
209 |
rc = ecryptfs_new_file_context(ecryptfs_inode); |
237fead61 [PATCH] ecryptfs:... |
210 |
if (rc) { |
d7cdc5feb eCryptfs: update ... |
211 212 213 214 |
ecryptfs_printk(KERN_ERR, "Error creating new file " "context; rc = [%d] ", rc); goto out; |
237fead61 [PATCH] ecryptfs:... |
215 |
} |
b59db43ad eCryptfs: Prevent... |
216 |
rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode); |
27992890b ecryptfs: test lo... |
217 218 |
if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " |
332ab16f8 eCryptfs: Add ref... |
219 |
"the lower file for the dentry with name " |
27992890b ecryptfs: test lo... |
220 221 222 223 |
"[%s]; rc = [%d] ", __func__, ecryptfs_dentry->d_name.name, rc); goto out; |
391b52f98 eCryptfs: Make al... |
224 |
} |
b59db43ad eCryptfs: Prevent... |
225 |
rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode); |
332ab16f8 eCryptfs: Add ref... |
226 |
if (rc) |
d7cdc5feb eCryptfs: update ... |
227 228 |
printk(KERN_ERR "Error writing headers; rc = [%d] ", rc); |
b59db43ad eCryptfs: Prevent... |
229 |
ecryptfs_put_lower_file(ecryptfs_inode); |
237fead61 [PATCH] ecryptfs:... |
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
out: return rc; } /** * 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. * @nd: nameidata * * 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, |
4acdaf27e switch ->create()... |
247 |
umode_t mode, struct nameidata *nd) |
237fead61 [PATCH] ecryptfs:... |
248 |
{ |
b59db43ad eCryptfs: Prevent... |
249 |
struct inode *ecryptfs_inode; |
237fead61 [PATCH] ecryptfs:... |
250 |
int rc; |
b59db43ad eCryptfs: Prevent... |
251 252 253 |
ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode); if (unlikely(IS_ERR(ecryptfs_inode))) { |
237fead61 [PATCH] ecryptfs:... |
254 255 256 |
ecryptfs_printk(KERN_WARNING, "Failed to create file in" "lower filesystem "); |
b59db43ad eCryptfs: Prevent... |
257 |
rc = PTR_ERR(ecryptfs_inode); |
237fead61 [PATCH] ecryptfs:... |
258 259 260 261 |
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 */ |
b59db43ad eCryptfs: Prevent... |
262 263 264 265 266 267 268 269 270 |
rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); if (rc) { drop_nlink(ecryptfs_inode); unlock_new_inode(ecryptfs_inode); iput(ecryptfs_inode); goto out; } d_instantiate(ecryptfs_dentry, ecryptfs_inode); unlock_new_inode(ecryptfs_inode); |
237fead61 [PATCH] ecryptfs:... |
271 272 273 |
out: return rc; } |
778aeb42a eCryptfs: Cleanup... |
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
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 " "[%s]; rc = [%d] ", __func__, dentry->d_name.name, 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; } |
237fead61 [PATCH] ecryptfs:... |
305 |
/** |
5ccf92037 eCryptfs: Cleanup... |
306 |
* ecryptfs_lookup_interpose - Dentry interposition for a lookup |
237fead61 [PATCH] ecryptfs:... |
307 |
*/ |
778aeb42a eCryptfs: Cleanup... |
308 |
static int ecryptfs_lookup_interpose(struct dentry *dentry, |
5ccf92037 eCryptfs: Cleanup... |
309 |
struct dentry *lower_dentry, |
778aeb42a eCryptfs: Cleanup... |
310 |
struct inode *dir_inode) |
237fead61 [PATCH] ecryptfs:... |
311 |
{ |
778aeb42a eCryptfs: Cleanup... |
312 313 |
struct inode *inode, *lower_inode = lower_dentry->d_inode; struct ecryptfs_dentry_info *dentry_info; |
237fead61 [PATCH] ecryptfs:... |
314 |
struct vfsmount *lower_mnt; |
778aeb42a eCryptfs: Cleanup... |
315 316 317 318 |
int rc = 0; lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); fsstack_copy_attr_atime(dir_inode, lower_dentry->d_parent->d_inode); |
b7ab39f63 fs: dcache scale ... |
319 |
BUG_ON(!lower_dentry->d_count); |
778aeb42a eCryptfs: Cleanup... |
320 321 322 323 |
dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL); ecryptfs_set_dentry_private(dentry, dentry_info); if (!dentry_info) { |
addd65ad8 eCryptfs: Filenam... |
324 325 326 327 |
printk(KERN_ERR "%s: Out of memory whilst attempting " "to allocate ecryptfs_dentry_info struct ", __func__); |
778aeb42a eCryptfs: Cleanup... |
328 329 330 331 |
dput(lower_dentry); mntput(lower_mnt); d_drop(dentry); return -ENOMEM; |
237fead61 [PATCH] ecryptfs:... |
332 |
} |
778aeb42a eCryptfs: Cleanup... |
333 334 |
ecryptfs_set_dentry_lower(dentry, lower_dentry); ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt); |
237fead61 [PATCH] ecryptfs:... |
335 336 |
if (!lower_dentry->d_inode) { /* We want to add because we couldn't find in lower */ |
778aeb42a eCryptfs: Cleanup... |
337 338 |
d_add(dentry, NULL); return 0; |
237fead61 [PATCH] ecryptfs:... |
339 |
} |
778aeb42a eCryptfs: Cleanup... |
340 |
inode = __ecryptfs_get_inode(lower_inode, dir_inode->i_sb); |
5ccf92037 eCryptfs: Cleanup... |
341 |
if (IS_ERR(inode)) { |
778aeb42a eCryptfs: Cleanup... |
342 343 344 345 |
printk(KERN_ERR "%s: Error interposing; rc = [%ld] ", __func__, PTR_ERR(inode)); return PTR_ERR(inode); |
391b52f98 eCryptfs: Make al... |
346 |
} |
778aeb42a eCryptfs: Cleanup... |
347 348 |
if (S_ISREG(inode->i_mode)) { rc = ecryptfs_i_size_read(dentry, inode); |
dd2a3b7ad [PATCH] eCryptfs:... |
349 |
if (rc) { |
778aeb42a eCryptfs: Cleanup... |
350 351 |
make_bad_inode(inode); return rc; |
237fead61 [PATCH] ecryptfs:... |
352 |
} |
237fead61 [PATCH] ecryptfs:... |
353 |
} |
778aeb42a eCryptfs: Cleanup... |
354 |
|
3b06b3ebf eCryptfs: Fix new... |
355 356 |
if (inode->i_state & I_NEW) unlock_new_inode(inode); |
778aeb42a eCryptfs: Cleanup... |
357 |
d_add(dentry, inode); |
addd65ad8 eCryptfs: Filenam... |
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
return rc; } /** * ecryptfs_lookup * @ecryptfs_dir_inode: The eCryptfs directory inode * @ecryptfs_dentry: The eCryptfs dentry that we are looking up * @ecryptfs_nd: nameidata; may be NULL * * 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, struct nameidata *ecryptfs_nd) { char *encrypted_and_encoded_name = NULL; |
a8f12864c eCryptfs: Fix dat... |
375 |
size_t encrypted_and_encoded_name_size; |
addd65ad8 eCryptfs: Filenam... |
376 |
struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; |
addd65ad8 eCryptfs: Filenam... |
377 378 |
struct dentry *lower_dir_dentry, *lower_dentry; int rc = 0; |
addd65ad8 eCryptfs: Filenam... |
379 380 381 382 383 384 385 |
if ((ecryptfs_dentry->d_name.len == 1 && !strcmp(ecryptfs_dentry->d_name.name, ".")) || (ecryptfs_dentry->d_name.len == 2 && !strcmp(ecryptfs_dentry->d_name.name, ".."))) { goto out_d_drop; } lower_dir_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry->d_parent); |
8787c7a3e eCryptfs: Revert ... |
386 387 388 389 390 |
mutex_lock(&lower_dir_dentry->d_inode->i_mutex); lower_dentry = lookup_one_len(ecryptfs_dentry->d_name.name, lower_dir_dentry, ecryptfs_dentry->d_name.len); mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
addd65ad8 eCryptfs: Filenam... |
391 392 |
if (IS_ERR(lower_dentry)) { rc = PTR_ERR(lower_dentry); |
8787c7a3e eCryptfs: Revert ... |
393 |
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
9f37622f8 eCryptfs: Turn lo... |
394 395 396 |
"[%d] on lower_dentry = [%s] ", __func__, rc, encrypted_and_encoded_name); |
addd65ad8 eCryptfs: Filenam... |
397 398 399 |
goto out_d_drop; } if (lower_dentry->d_inode) |
5ccf92037 eCryptfs: Cleanup... |
400 |
goto interpose; |
2aac0cf88 eCryptfs: NULL cr... |
401 402 403 404 |
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))) |
5ccf92037 eCryptfs: Cleanup... |
405 |
goto interpose; |
addd65ad8 eCryptfs: Filenam... |
406 407 408 |
dput(lower_dentry); rc = ecryptfs_encrypt_and_encode_filename( &encrypted_and_encoded_name, &encrypted_and_encoded_name_size, |
2aac0cf88 eCryptfs: NULL cr... |
409 |
NULL, mount_crypt_stat, ecryptfs_dentry->d_name.name, |
addd65ad8 eCryptfs: Filenam... |
410 411 412 413 414 415 416 |
ecryptfs_dentry->d_name.len); if (rc) { printk(KERN_ERR "%s: Error attempting to encrypt and encode " "filename; rc = [%d] ", __func__, rc); goto out_d_drop; } |
8787c7a3e eCryptfs: Revert ... |
417 418 419 420 421 |
mutex_lock(&lower_dir_dentry->d_inode->i_mutex); lower_dentry = lookup_one_len(encrypted_and_encoded_name, lower_dir_dentry, encrypted_and_encoded_name_size); mutex_unlock(&lower_dir_dentry->d_inode->i_mutex); |
addd65ad8 eCryptfs: Filenam... |
422 423 |
if (IS_ERR(lower_dentry)) { rc = PTR_ERR(lower_dentry); |
8787c7a3e eCryptfs: Revert ... |
424 |
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " |
9f37622f8 eCryptfs: Turn lo... |
425 426 427 |
"[%d] on lower_dentry = [%s] ", __func__, rc, encrypted_and_encoded_name); |
addd65ad8 eCryptfs: Filenam... |
428 429 |
goto out_d_drop; } |
5ccf92037 eCryptfs: Cleanup... |
430 431 432 |
interpose: rc = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry, ecryptfs_dir_inode); |
addd65ad8 eCryptfs: Filenam... |
433 434 435 |
goto out; out_d_drop: d_drop(ecryptfs_dentry); |
237fead61 [PATCH] ecryptfs:... |
436 |
out: |
addd65ad8 eCryptfs: Filenam... |
437 |
kfree(encrypted_and_encoded_name); |
237fead61 [PATCH] ecryptfs:... |
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 |
return ERR_PTR(rc); } 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(old_dentry->d_inode); 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, lower_dir_dentry->d_inode, lower_new_dentry); if (rc || !lower_new_dentry->d_inode) goto out_lock; |
5ccf92037 eCryptfs: Cleanup... |
460 |
rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb); |
237fead61 [PATCH] ecryptfs:... |
461 462 |
if (rc) goto out_lock; |
3a8380c07 eCryptfs: Copy lo... |
463 464 |
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); |
bfe868486 filesystems: add ... |
465 466 |
set_nlink(old_dentry->d_inode, ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink); |
237fead61 [PATCH] ecryptfs:... |
467 468 469 470 471 |
i_size_write(new_dentry->d_inode, file_size_save); out_lock: unlock_dir(lower_dir_dentry); dput(lower_new_dentry); dput(lower_old_dentry); |
237fead61 [PATCH] ecryptfs:... |
472 473 474 475 476 477 478 479 |
return rc; } static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) { int rc = 0; struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); |
8dc4e3736 ecryptfs: clean u... |
480 |
struct dentry *lower_dir_dentry; |
237fead61 [PATCH] ecryptfs:... |
481 |
|
9c2d20566 eCryptfs: Prevent... |
482 |
dget(lower_dentry); |
8dc4e3736 ecryptfs: clean u... |
483 |
lower_dir_dentry = lock_parent(lower_dentry); |
237fead61 [PATCH] ecryptfs:... |
484 485 |
rc = vfs_unlink(lower_dir_inode, lower_dentry); if (rc) { |
ae56fb163 [PATCH] eCryptfs:... |
486 487 |
printk(KERN_ERR "Error in vfs_unlink; rc = [%d] ", rc); |
237fead61 [PATCH] ecryptfs:... |
488 489 |
goto out_unlock; } |
0cc72dc7f [PATCH] eCryptfs:... |
490 |
fsstack_copy_attr_times(dir, lower_dir_inode); |
bfe868486 filesystems: add ... |
491 492 |
set_nlink(dentry->d_inode, ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink); |
237fead61 [PATCH] ecryptfs:... |
493 |
dentry->d_inode->i_ctime = dir->i_ctime; |
caeeeecfd eCryptfs: fix den... |
494 |
d_drop(dentry); |
237fead61 [PATCH] ecryptfs:... |
495 |
out_unlock: |
8dc4e3736 ecryptfs: clean u... |
496 |
unlock_dir(lower_dir_dentry); |
9c2d20566 eCryptfs: Prevent... |
497 |
dput(lower_dentry); |
237fead61 [PATCH] ecryptfs:... |
498 499 500 501 502 503 504 505 506 |
return rc; } static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { int rc; struct dentry *lower_dentry; struct dentry *lower_dir_dentry; |
237fead61 [PATCH] ecryptfs:... |
507 |
char *encoded_symname; |
addd65ad8 eCryptfs: Filenam... |
508 509 |
size_t encoded_symlen; struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL; |
237fead61 [PATCH] ecryptfs:... |
510 511 512 513 |
lower_dentry = ecryptfs_dentry_to_lower(dentry); dget(lower_dentry); lower_dir_dentry = lock_parent(lower_dentry); |
addd65ad8 eCryptfs: Filenam... |
514 515 516 517 518 519 520 521 |
mount_crypt_stat = &ecryptfs_superblock_to_private( dir->i_sb)->mount_crypt_stat; rc = ecryptfs_encrypt_and_encode_filename(&encoded_symname, &encoded_symlen, NULL, mount_crypt_stat, symname, strlen(symname)); if (rc) |
237fead61 [PATCH] ecryptfs:... |
522 |
goto out_lock; |
237fead61 [PATCH] ecryptfs:... |
523 |
rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, |
db2e747b1 [patch 5/5] vfs: ... |
524 |
encoded_symname); |
237fead61 [PATCH] ecryptfs:... |
525 526 527 |
kfree(encoded_symname); if (rc || !lower_dentry->d_inode) goto out_lock; |
5ccf92037 eCryptfs: Cleanup... |
528 |
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
237fead61 [PATCH] ecryptfs:... |
529 530 |
if (rc) goto out_lock; |
0cc72dc7f [PATCH] eCryptfs:... |
531 532 |
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); |
237fead61 [PATCH] ecryptfs:... |
533 534 535 536 537 538 539 |
out_lock: unlock_dir(lower_dir_dentry); dput(lower_dentry); if (!dentry->d_inode) d_drop(dentry); return rc; } |
18bb1db3e switch vfs_mkdir(... |
540 |
static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) |
237fead61 [PATCH] ecryptfs:... |
541 542 543 544 545 546 547 548 549 550 |
{ 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(lower_dir_dentry->d_inode, lower_dentry, mode); if (rc || !lower_dentry->d_inode) goto out; |
5ccf92037 eCryptfs: Cleanup... |
551 |
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
237fead61 [PATCH] ecryptfs:... |
552 553 |
if (rc) goto out; |
0cc72dc7f [PATCH] eCryptfs:... |
554 555 |
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); |
bfe868486 filesystems: add ... |
556 |
set_nlink(dir, lower_dir_dentry->d_inode->i_nlink); |
237fead61 [PATCH] ecryptfs:... |
557 558 559 560 561 562 563 564 565 |
out: unlock_dir(lower_dir_dentry); if (!dentry->d_inode) d_drop(dentry); return rc; } static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) { |
237fead61 [PATCH] ecryptfs:... |
566 |
struct dentry *lower_dentry; |
237fead61 [PATCH] ecryptfs:... |
567 |
struct dentry *lower_dir_dentry; |
45ec4abab [PATCH] eCryptfs:... |
568 |
int rc; |
237fead61 [PATCH] ecryptfs:... |
569 570 |
lower_dentry = ecryptfs_dentry_to_lower(dentry); |
45ec4abab [PATCH] eCryptfs:... |
571 |
dget(dentry); |
237fead61 [PATCH] ecryptfs:... |
572 |
lower_dir_dentry = lock_parent(lower_dentry); |
45ec4abab [PATCH] eCryptfs:... |
573 |
dget(lower_dentry); |
237fead61 [PATCH] ecryptfs:... |
574 |
rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); |
45ec4abab [PATCH] eCryptfs:... |
575 |
dput(lower_dentry); |
07850552b eCryptfs: Clear i... |
576 577 |
if (!rc && dentry->d_inode) clear_nlink(dentry->d_inode); |
0cc72dc7f [PATCH] eCryptfs:... |
578 |
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
bfe868486 filesystems: add ... |
579 |
set_nlink(dir, lower_dir_dentry->d_inode->i_nlink); |
237fead61 [PATCH] ecryptfs:... |
580 581 582 |
unlock_dir(lower_dir_dentry); if (!rc) d_drop(dentry); |
45ec4abab [PATCH] eCryptfs:... |
583 |
dput(dentry); |
237fead61 [PATCH] ecryptfs:... |
584 585 586 587 |
return rc; } static int |
1a67aafb5 switch ->mknod() ... |
588 |
ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) |
237fead61 [PATCH] ecryptfs:... |
589 590 591 592 593 594 595 596 597 598 |
{ 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(lower_dir_dentry->d_inode, lower_dentry, mode, dev); if (rc || !lower_dentry->d_inode) goto out; |
5ccf92037 eCryptfs: Cleanup... |
599 |
rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb); |
237fead61 [PATCH] ecryptfs:... |
600 601 |
if (rc) goto out; |
0cc72dc7f [PATCH] eCryptfs:... |
602 603 |
fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode); |
237fead61 [PATCH] ecryptfs:... |
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 |
out: unlock_dir(lower_dir_dentry); if (!dentry->d_inode) d_drop(dentry); return rc; } static int ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { int rc; struct dentry *lower_old_dentry; struct dentry *lower_new_dentry; struct dentry *lower_old_dir_dentry; struct dentry *lower_new_dir_dentry; |
0d132f736 ecryptfs: don't i... |
620 |
struct dentry *trap = NULL; |
237fead61 [PATCH] ecryptfs:... |
621 622 623 624 625 626 627 |
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); |
0d132f736 ecryptfs: don't i... |
628 629 630 631 632 633 634 635 636 637 638 |
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; } |
237fead61 [PATCH] ecryptfs:... |
639 640 641 642 |
rc = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry, lower_new_dir_dentry->d_inode, lower_new_dentry); if (rc) goto out_lock; |
9afa2fb6c fsstack/ecryptfs:... |
643 |
fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); |
237fead61 [PATCH] ecryptfs:... |
644 |
if (new_dir != old_dir) |
9afa2fb6c fsstack/ecryptfs:... |
645 |
fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); |
237fead61 [PATCH] ecryptfs:... |
646 647 |
out_lock: unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
dd55c8985 eCryptfs: dput de... |
648 649 |
dput(lower_new_dir_dentry); dput(lower_old_dir_dentry); |
237fead61 [PATCH] ecryptfs:... |
650 651 652 653 |
dput(lower_new_dentry); dput(lower_old_dentry); return rc; } |
3a60a1686 eCryptfs: Decrypt... |
654 655 |
static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf, size_t *bufsiz) |
237fead61 [PATCH] ecryptfs:... |
656 |
{ |
3a60a1686 eCryptfs: Decrypt... |
657 |
struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); |
237fead61 [PATCH] ecryptfs:... |
658 |
char *lower_buf; |
3a60a1686 eCryptfs: Decrypt... |
659 |
size_t lower_bufsiz = PATH_MAX; |
addd65ad8 eCryptfs: Filenam... |
660 661 |
mm_segment_t old_fs; int rc; |
237fead61 [PATCH] ecryptfs:... |
662 |
|
3a6b42cad eCryptfs: Larger ... |
663 |
lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL); |
3a60a1686 eCryptfs: Decrypt... |
664 |
if (!lower_buf) { |
237fead61 [PATCH] ecryptfs:... |
665 666 667 668 669 |
rc = -ENOMEM; goto out; } old_fs = get_fs(); set_fs(get_ds()); |
237fead61 [PATCH] ecryptfs:... |
670 671 |
rc = lower_dentry->d_inode->i_op->readlink(lower_dentry, (char __user *)lower_buf, |
3a6b42cad eCryptfs: Larger ... |
672 |
lower_bufsiz); |
237fead61 [PATCH] ecryptfs:... |
673 |
set_fs(old_fs); |
3a60a1686 eCryptfs: Decrypt... |
674 675 676 677 678 679 |
if (rc < 0) goto out; lower_bufsiz = rc; rc = ecryptfs_decode_and_decrypt_filename(buf, bufsiz, dentry, lower_buf, lower_bufsiz); out: |
237fead61 [PATCH] ecryptfs:... |
680 |
kfree(lower_buf); |
3a60a1686 eCryptfs: Decrypt... |
681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 |
return rc; } static int ecryptfs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) { char *kbuf; size_t kbufsiz, copied; int rc; rc = ecryptfs_readlink_lower(dentry, &kbuf, &kbufsiz); if (rc) goto out; copied = min_t(size_t, bufsiz, kbufsiz); rc = copy_to_user(buf, kbuf, copied) ? -EFAULT : copied; kfree(kbuf); fsstack_copy_attr_atime(dentry->d_inode, ecryptfs_dentry_to_lower(dentry)->d_inode); |
237fead61 [PATCH] ecryptfs:... |
699 700 701 702 703 704 705 706 707 708 709 710 711 |
out: return rc; } static void *ecryptfs_follow_link(struct dentry *dentry, struct nameidata *nd) { char *buf; int len = PAGE_SIZE, rc; mm_segment_t old_fs; /* Released in ecryptfs_put_link(); only release here on error */ buf = kmalloc(len, GFP_KERNEL); if (!buf) { |
806892e9e ecryptfs: Fix ref... |
712 |
buf = ERR_PTR(-ENOMEM); |
237fead61 [PATCH] ecryptfs:... |
713 714 715 716 |
goto out; } old_fs = get_fs(); set_fs(get_ds()); |
237fead61 [PATCH] ecryptfs:... |
717 |
rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); |
237fead61 [PATCH] ecryptfs:... |
718 |
set_fs(old_fs); |
806892e9e ecryptfs: Fix ref... |
719 720 721 722 |
if (rc < 0) { kfree(buf); buf = ERR_PTR(rc); } else |
a17d5232d eCryptfs: check r... |
723 |
buf[rc] = '\0'; |
237fead61 [PATCH] ecryptfs:... |
724 |
out: |
806892e9e ecryptfs: Fix ref... |
725 726 |
nd_set_link(nd, buf); return NULL; |
237fead61 [PATCH] ecryptfs:... |
727 728 729 730 731 |
} static void ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) { |
806892e9e ecryptfs: Fix ref... |
732 733 734 735 736 |
char *buf = nd_get_link(nd); if (!IS_ERR(buf)) { /* Free the char* */ kfree(buf); } |
237fead61 [PATCH] ecryptfs:... |
737 738 739 740 741 742 743 |
} /** * upper_size_to_lower_size * @crypt_stat: Crypt_stat associated with file * @upper_size: Size of the upper file * |
cc11beffd eCryptfs: track h... |
744 |
* Calculate the required size of the lower file based on the |
237fead61 [PATCH] ecryptfs:... |
745 746 747 748 749 750 751 752 753 754 |
* specified size of the upper file. This calculation is based on the * number of headers in the underlying file and the extent size. * * Returns Calculated size of the lower file. */ static loff_t upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, loff_t upper_size) { loff_t lower_size; |
157f10713 eCryptfs: Fix met... |
755 |
lower_size = ecryptfs_lower_header_size(crypt_stat); |
237fead61 [PATCH] ecryptfs:... |
756 757 758 759 760 761 762 763 764 765 766 767 |
if (upper_size != 0) { loff_t num_extents; num_extents = upper_size >> crypt_stat->extent_shift; if (upper_size & ~crypt_stat->extent_mask) num_extents++; lower_size += (num_extents * crypt_stat->extent_size); } return lower_size; } /** |
5f3ef64f4 eCryptfs: Use not... |
768 |
* truncate_upper |
237fead61 [PATCH] ecryptfs:... |
769 |
* @dentry: The ecryptfs layer dentry |
5f3ef64f4 eCryptfs: Use not... |
770 771 |
* @ia: Address of the ecryptfs inode's attributes * @lower_ia: Address of the lower inode's attributes |
237fead61 [PATCH] ecryptfs:... |
772 773 774 |
* * Function to handle truncations modifying the size of the file. Note * that the file sizes are interpolated. When expanding, we are simply |
5f3ef64f4 eCryptfs: Use not... |
775 776 777 778 779 |
* writing strings of 0's out. When truncating, we truncate the upper * inode and update the lower_ia according to the page index * interpolations. If ATTR_SIZE is set in lower_ia->ia_valid upon return, * the caller must use lower_ia in a call to notify_change() to perform * the truncation of the lower inode. |
237fead61 [PATCH] ecryptfs:... |
780 781 782 |
* * Returns zero on success; non-zero otherwise */ |
5f3ef64f4 eCryptfs: Use not... |
783 784 |
static int truncate_upper(struct dentry *dentry, struct iattr *ia, struct iattr *lower_ia) |
237fead61 [PATCH] ecryptfs:... |
785 786 787 |
{ int rc = 0; struct inode *inode = dentry->d_inode; |
237fead61 [PATCH] ecryptfs:... |
788 789 790 791 |
struct ecryptfs_crypt_stat *crypt_stat; loff_t i_size = i_size_read(inode); loff_t lower_size_before_truncate; loff_t lower_size_after_truncate; |
5f3ef64f4 eCryptfs: Use not... |
792 793 |
if (unlikely((ia->ia_size == i_size))) { lower_ia->ia_valid &= ~ATTR_SIZE; |
332ab16f8 eCryptfs: Add ref... |
794 |
return 0; |
5f3ef64f4 eCryptfs: Use not... |
795 |
} |
3b06b3ebf eCryptfs: Fix new... |
796 |
rc = ecryptfs_get_lower_file(dentry, inode); |
332ab16f8 eCryptfs: Add ref... |
797 798 |
if (rc) return rc; |
237fead61 [PATCH] ecryptfs:... |
799 |
crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
237fead61 [PATCH] ecryptfs:... |
800 |
/* Switch on growing or shrinking file */ |
5f3ef64f4 eCryptfs: Use not... |
801 |
if (ia->ia_size > i_size) { |
2ed92554a eCryptfs: make op... |
802 |
char zero[] = { 0x00 }; |
5f3ef64f4 eCryptfs: Use not... |
803 |
lower_ia->ia_valid &= ~ATTR_SIZE; |
2ed92554a eCryptfs: make op... |
804 805 806 807 |
/* Write a single 0 at the last position of the file; * this triggers code that will fill in 0's throughout * the intermediate portion of the previous end of the * file and the new and of the file */ |
48c1e44ac switch ecryptfs_w... |
808 |
rc = ecryptfs_write(inode, zero, |
5f3ef64f4 eCryptfs: Use not... |
809 810 811 812 813 |
(ia->ia_size - 1), 1); } else { /* ia->ia_size < i_size_read(inode) */ /* We're chopping off all the pages down to the page * in which ia->ia_size is located. Fill in the end of * that page from (ia->ia_size & ~PAGE_CACHE_MASK) to |
2ed92554a eCryptfs: make op... |
814 815 |
* PAGE_CACHE_SIZE with zeros. */ size_t num_zeros = (PAGE_CACHE_SIZE |
5f3ef64f4 eCryptfs: Use not... |
816 |
- (ia->ia_size & ~PAGE_CACHE_MASK)); |
2ed92554a eCryptfs: make op... |
817 |
|
2c27c65ed check ATTR_SIZE c... |
818 819 820 821 822 823 824 825 826 827 828 |
/* * XXX(truncate) this should really happen at the begginning * of ->setattr. But the code is too messy to that as part * of a larger patch. ecryptfs is also totally missing out * on the inode_change_ok check at the beginning of * ->setattr while would include this. */ rc = inode_newsize_ok(inode, ia->ia_size); if (rc) goto out; |
13a791b4e eCryptfs: Fix dat... |
829 |
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
2c27c65ed check ATTR_SIZE c... |
830 |
truncate_setsize(inode, ia->ia_size); |
5f3ef64f4 eCryptfs: Use not... |
831 832 |
lower_ia->ia_size = ia->ia_size; lower_ia->ia_valid |= ATTR_SIZE; |
48c1e44ac switch ecryptfs_w... |
833 |
goto out; |
13a791b4e eCryptfs: Fix dat... |
834 |
} |
2ed92554a eCryptfs: make op... |
835 836 837 838 839 840 |
if (num_zeros) { char *zeros_virt; zeros_virt = kzalloc(num_zeros, GFP_KERNEL); if (!zeros_virt) { rc = -ENOMEM; |
48c1e44ac switch ecryptfs_w... |
841 |
goto out; |
2ed92554a eCryptfs: make op... |
842 |
} |
48c1e44ac switch ecryptfs_w... |
843 |
rc = ecryptfs_write(inode, zeros_virt, |
5f3ef64f4 eCryptfs: Use not... |
844 |
ia->ia_size, num_zeros); |
2ed92554a eCryptfs: make op... |
845 |
kfree(zeros_virt); |
5dda6992a eCryptfs: remove ... |
846 |
if (rc) { |
240e2df5c eCryptfs: fix wri... |
847 848 849 850 |
printk(KERN_ERR "Error attempting to zero out " "the remainder of the end page on " "reducing truncate; rc = [%d] ", rc); |
48c1e44ac switch ecryptfs_w... |
851 |
goto out; |
240e2df5c eCryptfs: fix wri... |
852 853 |
} } |
2c27c65ed check ATTR_SIZE c... |
854 |
truncate_setsize(inode, ia->ia_size); |
0216f7f79 eCryptfs: replace... |
855 |
rc = ecryptfs_write_inode_size_to_metadata(inode); |
dd2a3b7ad [PATCH] eCryptfs:... |
856 857 858 859 860 |
if (rc) { printk(KERN_ERR "Problem with " "ecryptfs_write_inode_size_to_metadata; " "rc = [%d] ", rc); |
48c1e44ac switch ecryptfs_w... |
861 |
goto out; |
dd2a3b7ad [PATCH] eCryptfs:... |
862 |
} |
237fead61 [PATCH] ecryptfs:... |
863 864 865 866 867 |
/* We are reducing the size of the ecryptfs file, and need to * know if we need to reduce the size of the lower file. */ lower_size_before_truncate = upper_size_to_lower_size(crypt_stat, i_size); lower_size_after_truncate = |
5f3ef64f4 eCryptfs: Use not... |
868 869 870 871 872 873 |
upper_size_to_lower_size(crypt_stat, ia->ia_size); if (lower_size_after_truncate < lower_size_before_truncate) { lower_ia->ia_size = lower_size_after_truncate; lower_ia->ia_valid |= ATTR_SIZE; } else lower_ia->ia_valid &= ~ATTR_SIZE; |
237fead61 [PATCH] ecryptfs:... |
874 |
} |
237fead61 [PATCH] ecryptfs:... |
875 |
out: |
332ab16f8 eCryptfs: Add ref... |
876 |
ecryptfs_put_lower_file(inode); |
237fead61 [PATCH] ecryptfs:... |
877 878 |
return rc; } |
5f3ef64f4 eCryptfs: Use not... |
879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 |
/** * ecryptfs_truncate * @dentry: The ecryptfs layer dentry * @new_length: The length to expand the file to * * Simple function that handles the truncation of an eCryptfs inode and * its corresponding lower inode. * * Returns zero on success; non-zero otherwise */ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) { struct iattr ia = { .ia_valid = ATTR_SIZE, .ia_size = new_length }; struct iattr lower_ia = { .ia_valid = 0 }; int rc; rc = truncate_upper(dentry, &ia, &lower_ia); if (!rc && lower_ia.ia_valid & ATTR_SIZE) { struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); mutex_lock(&lower_dentry->d_inode->i_mutex); rc = notify_change(lower_dentry, &lower_ia); mutex_unlock(&lower_dentry->d_inode->i_mutex); } return rc; } |
237fead61 [PATCH] ecryptfs:... |
905 |
static int |
10556cb21 ->permission() sa... |
906 |
ecryptfs_permission(struct inode *inode, int mask) |
237fead61 [PATCH] ecryptfs:... |
907 |
{ |
f419a2e3b [PATCH] kill name... |
908 |
return inode_permission(ecryptfs_inode_to_lower(inode), mask); |
237fead61 [PATCH] ecryptfs:... |
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 |
} /** * ecryptfs_setattr * @dentry: dentry handle to the inode to modify * @ia: Structure with flags of what to change and values * * Updates the metadata of an inode. If the update is to the size * i.e. truncation, then ecryptfs_truncate will handle the size modification * of both the ecryptfs inode and the lower inode. * * All other metadata changes will be passed right to the lower filesystem, * and we will just update our inode to look like the lower. */ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) { int rc = 0; struct dentry *lower_dentry; |
5f3ef64f4 eCryptfs: Use not... |
927 |
struct iattr lower_ia; |
237fead61 [PATCH] ecryptfs:... |
928 929 930 931 932 |
struct inode *inode; struct inode *lower_inode; struct ecryptfs_crypt_stat *crypt_stat; crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
e10f281bc eCryptfs: initial... |
933 934 |
if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) ecryptfs_init_crypt_stat(crypt_stat); |
237fead61 [PATCH] ecryptfs:... |
935 936 |
inode = dentry->d_inode; lower_inode = ecryptfs_inode_to_lower(inode); |
e10f281bc eCryptfs: initial... |
937 938 939 940 |
lower_dentry = ecryptfs_dentry_to_lower(dentry); mutex_lock(&crypt_stat->cs_mutex); if (S_ISDIR(dentry->d_inode->i_mode)) crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
64ee4808a eCryptfs: ecryptf... |
941 942 943 |
else if (S_ISREG(dentry->d_inode->i_mode) && (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) || !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) { |
e10f281bc eCryptfs: initial... |
944 |
struct ecryptfs_mount_crypt_stat *mount_crypt_stat; |
e10f281bc eCryptfs: initial... |
945 |
|
e10f281bc eCryptfs: initial... |
946 947 |
mount_crypt_stat = &ecryptfs_superblock_to_private( dentry->d_sb)->mount_crypt_stat; |
3b06b3ebf eCryptfs: Fix new... |
948 |
rc = ecryptfs_get_lower_file(dentry, inode); |
332ab16f8 eCryptfs: Add ref... |
949 950 951 952 |
if (rc) { mutex_unlock(&crypt_stat->cs_mutex); goto out; } |
d7cdc5feb eCryptfs: update ... |
953 |
rc = ecryptfs_read_metadata(dentry); |
332ab16f8 eCryptfs: Add ref... |
954 |
ecryptfs_put_lower_file(inode); |
5dda6992a eCryptfs: remove ... |
955 |
if (rc) { |
e10f281bc eCryptfs: initial... |
956 957 958 |
if (!(mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { rc = -EIO; |
25bd81740 eCryptfs: Minor f... |
959 |
printk(KERN_WARNING "Either the lower file " |
e10f281bc eCryptfs: initial... |
960 |
"is not in a valid eCryptfs format, " |
25bd81740 eCryptfs: Minor f... |
961 962 |
"or the key could not be retrieved. " "Plaintext passthrough mode is not " |
e10f281bc eCryptfs: initial... |
963 964 |
"enabled; returning -EIO "); |
e10f281bc eCryptfs: initial... |
965 |
mutex_unlock(&crypt_stat->cs_mutex); |
e10f281bc eCryptfs: initial... |
966 967 968 |
goto out; } rc = 0; |
3aeb86ea4 eCryptfs: Handle ... |
969 970 |
crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ECRYPTFS_ENCRYPTED); |
e10f281bc eCryptfs: initial... |
971 |
} |
e10f281bc eCryptfs: initial... |
972 973 |
} mutex_unlock(&crypt_stat->cs_mutex); |
5be79de2e eCryptfs: Flush d... |
974 975 976 977 978 979 |
if (S_ISREG(inode->i_mode)) { rc = filemap_write_and_wait(inode->i_mapping); if (rc) goto out; fsstack_copy_attr_all(inode, lower_inode); } |
5f3ef64f4 eCryptfs: Use not... |
980 981 982 |
memcpy(&lower_ia, ia, sizeof(lower_ia)); if (ia->ia_valid & ATTR_FILE) lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); |
237fead61 [PATCH] ecryptfs:... |
983 |
if (ia->ia_valid & ATTR_SIZE) { |
5f3ef64f4 eCryptfs: Use not... |
984 |
rc = truncate_upper(dentry, ia, &lower_ia); |
237fead61 [PATCH] ecryptfs:... |
985 986 987 |
if (rc < 0) goto out; } |
1ac564eca ecryptfs: allow l... |
988 989 990 991 992 |
/* * mode change is for clearing setuid/setgid bits. Allow lower fs * to interpret this in its own way. */ |
5f3ef64f4 eCryptfs: Use not... |
993 994 |
if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) lower_ia.ia_valid &= ~ATTR_MODE; |
1ac564eca ecryptfs: allow l... |
995 |
|
9c3580aa5 ecryptfs: add mis... |
996 |
mutex_lock(&lower_dentry->d_inode->i_mutex); |
5f3ef64f4 eCryptfs: Use not... |
997 |
rc = notify_change(lower_dentry, &lower_ia); |
9c3580aa5 ecryptfs: add mis... |
998 |
mutex_unlock(&lower_dentry->d_inode->i_mutex); |
237fead61 [PATCH] ecryptfs:... |
999 |
out: |
9afa2fb6c fsstack/ecryptfs:... |
1000 |
fsstack_copy_attr_all(inode, lower_inode); |
237fead61 [PATCH] ecryptfs:... |
1001 1002 |
return rc; } |
3a60a1686 eCryptfs: Decrypt... |
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 |
int ecryptfs_getattr_link(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct ecryptfs_mount_crypt_stat *mount_crypt_stat; int rc = 0; mount_crypt_stat = &ecryptfs_superblock_to_private( dentry->d_sb)->mount_crypt_stat; generic_fillattr(dentry->d_inode, stat); if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) { char *target; size_t targetsiz; rc = ecryptfs_readlink_lower(dentry, &target, &targetsiz); if (!rc) { kfree(target); stat->size = targetsiz; } } return rc; } |
f8f484d1b eCryptfs: Add get... |
1024 1025 1026 1027 1028 1029 1030 1031 1032 |
int ecryptfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct kstat lower_stat; int rc; rc = vfs_getattr(ecryptfs_dentry_to_lower_mnt(dentry), ecryptfs_dentry_to_lower(dentry), &lower_stat); if (!rc) { |
55f9cf6bb eCryptfs: Copy up... |
1033 1034 |
fsstack_copy_attr_all(dentry->d_inode, ecryptfs_inode_to_lower(dentry->d_inode)); |
f8f484d1b eCryptfs: Add get... |
1035 1036 1037 1038 1039 |
generic_fillattr(dentry->d_inode, stat); stat->blocks = lower_stat.blocks; } return rc; } |
dd2a3b7ad [PATCH] eCryptfs:... |
1040 |
int |
237fead61 [PATCH] ecryptfs:... |
1041 1042 1043 1044 1045 1046 1047 1048 |
ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { int rc = 0; struct dentry *lower_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); if (!lower_dentry->d_inode->i_op->setxattr) { |
cfce08c6b ecryptfs: fix err... |
1049 |
rc = -EOPNOTSUPP; |
237fead61 [PATCH] ecryptfs:... |
1050 1051 |
goto out; } |
48b512e68 ecryptfs: call vf... |
1052 1053 |
rc = vfs_setxattr(lower_dentry, name, value, size, flags); |
237fead61 [PATCH] ecryptfs:... |
1054 1055 1056 |
out: return rc; } |
dd2a3b7ad [PATCH] eCryptfs:... |
1057 |
ssize_t |
d7cdc5feb eCryptfs: update ... |
1058 1059 1060 1061 1062 1063 |
ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, void *value, size_t size) { int rc = 0; if (!lower_dentry->d_inode->i_op->getxattr) { |
cfce08c6b ecryptfs: fix err... |
1064 |
rc = -EOPNOTSUPP; |
d7cdc5feb eCryptfs: update ... |
1065 1066 1067 1068 1069 1070 1071 1072 1073 |
goto out; } mutex_lock(&lower_dentry->d_inode->i_mutex); rc = lower_dentry->d_inode->i_op->getxattr(lower_dentry, name, value, size); mutex_unlock(&lower_dentry->d_inode->i_mutex); out: return rc; } |
7896b6318 fs/ecryptfs/: pos... |
1074 |
static ssize_t |
237fead61 [PATCH] ecryptfs:... |
1075 1076 1077 |
ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) { |
2ed92554a eCryptfs: make op... |
1078 1079 |
return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), name, value, size); |
237fead61 [PATCH] ecryptfs:... |
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 |
} static ssize_t ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) { int rc = 0; struct dentry *lower_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); if (!lower_dentry->d_inode->i_op->listxattr) { |
cfce08c6b ecryptfs: fix err... |
1090 |
rc = -EOPNOTSUPP; |
237fead61 [PATCH] ecryptfs:... |
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 |
goto out; } mutex_lock(&lower_dentry->d_inode->i_mutex); rc = lower_dentry->d_inode->i_op->listxattr(lower_dentry, list, size); mutex_unlock(&lower_dentry->d_inode->i_mutex); out: return rc; } static int ecryptfs_removexattr(struct dentry *dentry, const char *name) { int rc = 0; struct dentry *lower_dentry; lower_dentry = ecryptfs_dentry_to_lower(dentry); if (!lower_dentry->d_inode->i_op->removexattr) { |
cfce08c6b ecryptfs: fix err... |
1107 |
rc = -EOPNOTSUPP; |
237fead61 [PATCH] ecryptfs:... |
1108 1109 1110 1111 1112 1113 1114 1115 |
goto out; } mutex_lock(&lower_dentry->d_inode->i_mutex); rc = lower_dentry->d_inode->i_op->removexattr(lower_dentry, name); mutex_unlock(&lower_dentry->d_inode->i_mutex); out: return rc; } |
754661f14 [PATCH] mark stru... |
1116 |
const struct inode_operations ecryptfs_symlink_iops = { |
237fead61 [PATCH] ecryptfs:... |
1117 1118 1119 1120 1121 |
.readlink = ecryptfs_readlink, .follow_link = ecryptfs_follow_link, .put_link = ecryptfs_put_link, .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, |
3a60a1686 eCryptfs: Decrypt... |
1122 |
.getattr = ecryptfs_getattr_link, |
237fead61 [PATCH] ecryptfs:... |
1123 1124 1125 1126 1127 |
.setxattr = ecryptfs_setxattr, .getxattr = ecryptfs_getxattr, .listxattr = ecryptfs_listxattr, .removexattr = ecryptfs_removexattr }; |
754661f14 [PATCH] mark stru... |
1128 |
const struct inode_operations ecryptfs_dir_iops = { |
237fead61 [PATCH] ecryptfs:... |
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 |
.create = ecryptfs_create, .lookup = ecryptfs_lookup, .link = ecryptfs_link, .unlink = ecryptfs_unlink, .symlink = ecryptfs_symlink, .mkdir = ecryptfs_mkdir, .rmdir = ecryptfs_rmdir, .mknod = ecryptfs_mknod, .rename = ecryptfs_rename, .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, .setxattr = ecryptfs_setxattr, .getxattr = ecryptfs_getxattr, .listxattr = ecryptfs_listxattr, .removexattr = ecryptfs_removexattr }; |
754661f14 [PATCH] mark stru... |
1145 |
const struct inode_operations ecryptfs_main_iops = { |
237fead61 [PATCH] ecryptfs:... |
1146 1147 |
.permission = ecryptfs_permission, .setattr = ecryptfs_setattr, |
f8f484d1b eCryptfs: Add get... |
1148 |
.getattr = ecryptfs_getattr, |
237fead61 [PATCH] ecryptfs:... |
1149 1150 1151 1152 1153 |
.setxattr = ecryptfs_setxattr, .getxattr = ecryptfs_getxattr, .listxattr = ecryptfs_listxattr, .removexattr = ecryptfs_removexattr }; |