Blame view

fs/ecryptfs/inode.c 32.9 KB
237fead61   Michael Halcrow   [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   Michael Halcrow   [PATCH] eCryptfs:...
6
   * Copyright (C) 2004-2007 International Business Machines Corp.
237fead61   Michael Halcrow   [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   Josef "Jeff" Sipek   [PATCH] eCryptfs:...
33
  #include <linux/fs_stack.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
34
  #include <linux/slab.h>
48b512e68   Roberto Sassu   ecryptfs: call vf...
35
  #include <linux/xattr.h>
0a688ad71   Harvey Harrison   ecryptfs: inode.c...
36
  #include <asm/unaligned.h>
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
37
38
39
40
41
  #include "ecryptfs_kernel.h"
  
  static struct dentry *lock_parent(struct dentry *dentry)
  {
  	struct dentry *dir;
8dc4e3736   Miklos Szeredi   ecryptfs: clean u...
42
  	dir = dget_parent(dentry);
908e0a8a2   Peter Zijlstra   [PATCH] ecryptfs:...
43
  	mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
44
45
  	return dir;
  }
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
46
47
48
49
50
  static void unlock_dir(struct dentry *dir)
  {
  	mutex_unlock(&dir->d_inode->i_mutex);
  	dput(dir);
  }
c4f790736   Tyler Hicks   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   Tyler Hicks   eCryptfs: Cleanup...
57
  static int ecryptfs_inode_set(struct inode *inode, void *opaque)
c4f790736   Tyler Hicks   eCryptfs: Consoli...
58
  {
5ccf92037   Tyler Hicks   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   Tyler Hicks   eCryptfs: Consoli...
66
  	inode->i_version++;
c4f790736   Tyler Hicks   eCryptfs: Consoli...
67
  	inode->i_mapping->a_ops = &ecryptfs_aops;
985ca0e62   Thieu Le   ecryptfs: Make in...
68
  	inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi;
5ccf92037   Tyler Hicks   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   Tyler Hicks   eCryptfs: Consoli...
83
84
  	return 0;
  }
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
85
86
  static struct inode *__ecryptfs_get_inode(struct inode *lower_inode,
  					  struct super_block *sb)
c4f790736   Tyler Hicks   eCryptfs: Consoli...
87
88
  {
  	struct inode *inode;
c4f790736   Tyler Hicks   eCryptfs: Consoli...
89

5ccf92037   Tyler Hicks   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   Tyler Hicks   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   Tyler Hicks   eCryptfs: Consoli...
98
  		iput(lower_inode);
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
99
  		return ERR_PTR(-EACCES);
c4f790736   Tyler Hicks   eCryptfs: Consoli...
100
  	}
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
101
  	if (!(inode->i_state & I_NEW))
c4f790736   Tyler Hicks   eCryptfs: Consoli...
102
  		iput(lower_inode);
5ccf92037   Tyler Hicks   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   Tyler Hicks   eCryptfs: Consoli...
114
  	return inode;
c4f790736   Tyler Hicks   eCryptfs: Consoli...
115
  }
c4f790736   Tyler Hicks   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   Tyler Hicks   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   Tyler Hicks   eCryptfs: Cleanup...
127
  			      struct dentry *dentry, struct super_block *sb)
c4f790736   Tyler Hicks   eCryptfs: Consoli...
128
  {
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
129
  	struct inode *inode = ecryptfs_get_inode(lower_dentry->d_inode, sb);
c4f790736   Tyler Hicks   eCryptfs: Consoli...
130
131
  	if (IS_ERR(inode))
  		return PTR_ERR(inode);
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
132
  	d_instantiate(dentry, inode);
c4f790736   Tyler Hicks   eCryptfs: Consoli...
133
134
  	return 0;
  }
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
135
  /**
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Prevent...
146
   * Returns the new eCryptfs inode on success; an ERR_PTR on error condition
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
147
   */
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
148
  static struct inode *
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
149
  ecryptfs_do_create(struct inode *directory_inode,
175a4eb7e   Al Viro   fs: propagate umo...
150
  		   struct dentry *ecryptfs_dentry, umode_t mode)
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
151
152
153
154
  {
  	int rc;
  	struct dentry *lower_dentry;
  	struct dentry *lower_dir_dentry;
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
155
  	struct inode *inode;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
156
157
158
  
  	lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
  	lower_dir_dentry = lock_parent(lower_dentry);
801678c5a   Hirofumi Nakagawa   Remove duplicated...
159
  	if (IS_ERR(lower_dir_dentry)) {
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
160
161
162
  		ecryptfs_printk(KERN_ERR, "Error locking directory of "
  				"dentry
  ");
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
163
  		inode = ERR_CAST(lower_dir_dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
164
165
  		goto out;
  	}
18cb1b08d   Al Viro   kill ecryptfs_cre...
166
  	rc = vfs_create(lower_dir_dentry->d_inode, lower_dentry, mode, NULL);
4981e081c   Michael Halcrow   eCryptfs: set up ...
167
  	if (rc) {
caeeeecfd   Michael Halcrow   eCryptfs: fix den...
168
  		printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
18d1dbf1d   Harvey Harrison   ecryptfs: replace...
169
170
  		       "rc = [%d]
  ", __func__, rc);
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
171
  		inode = ERR_PTR(rc);
caeeeecfd   Michael Halcrow   eCryptfs: fix den...
172
  		goto out_lock;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
173
  	}
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
174
175
176
  	inode = __ecryptfs_get_inode(lower_dentry->d_inode,
  				     directory_inode->i_sb);
  	if (IS_ERR(inode))
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
177
  		goto out_lock;
0cc72dc7f   Josef "Jeff" Sipek   [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   Michael Halcrow   [PATCH] ecryptfs:...
180
181
182
  out_lock:
  	unlock_dir(lower_dir_dentry);
  out:
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
183
  	return inode;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
184
185
186
  }
  
  /**
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Prevent...
194
195
  static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry,
  				    struct inode *ecryptfs_inode)
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
196
  {
d7cdc5feb   Michael Halcrow   eCryptfs: update ...
197
  	struct ecryptfs_crypt_stat *crypt_stat =
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
198
  		&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
199
  	int rc = 0;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
200

b59db43ad   Tyler Hicks   eCryptfs: Prevent...
201
  	if (S_ISDIR(ecryptfs_inode->i_mode)) {
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
202
203
  		ecryptfs_printk(KERN_DEBUG, "This is a directory
  ");
e2bd99ec5   Michael Halcrow   [PATCH] eCryptfs:...
204
  		crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
d7cdc5feb   Michael Halcrow   eCryptfs: update ...
205
  		goto out;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
206
  	}
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
207
208
  	ecryptfs_printk(KERN_DEBUG, "Initializing crypto context
  ");
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
209
  	rc = ecryptfs_new_file_context(ecryptfs_inode);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
210
  	if (rc) {
d7cdc5feb   Michael Halcrow   eCryptfs: update ...
211
212
213
214
  		ecryptfs_printk(KERN_ERR, "Error creating new file "
  				"context; rc = [%d]
  ", rc);
  		goto out;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
215
  	}
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
216
  	rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode);
27992890b   Roberto Sassu   ecryptfs: test lo...
217
218
  	if (rc) {
  		printk(KERN_ERR "%s: Error attempting to initialize "
332ab16f8   Tyler Hicks   eCryptfs: Add ref...
219
  			"the lower file for the dentry with name "
27992890b   Roberto Sassu   ecryptfs: test lo...
220
221
222
223
  			"[%s]; rc = [%d]
  ", __func__,
  			ecryptfs_dentry->d_name.name, rc);
  		goto out;
391b52f98   Michael Halcrow   eCryptfs: Make al...
224
  	}
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
225
  	rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode);
332ab16f8   Tyler Hicks   eCryptfs: Add ref...
226
  	if (rc)
d7cdc5feb   Michael Halcrow   eCryptfs: update ...
227
228
  		printk(KERN_ERR "Error writing headers; rc = [%d]
  ", rc);
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
229
  	ecryptfs_put_lower_file(ecryptfs_inode);
237fead61   Michael Halcrow   [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   Al Viro   switch ->create()...
247
  		umode_t mode, struct nameidata *nd)
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
248
  {
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
249
  	struct inode *ecryptfs_inode;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
250
  	int rc;
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
251
252
253
  	ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry,
  					    mode);
  	if (unlikely(IS_ERR(ecryptfs_inode))) {
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
254
255
256
  		ecryptfs_printk(KERN_WARNING, "Failed to create file in"
  				"lower filesystem
  ");
b59db43ad   Tyler Hicks   eCryptfs: Prevent...
257
  		rc = PTR_ERR(ecryptfs_inode);
237fead61   Michael Halcrow   [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   Tyler Hicks   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   Michael Halcrow   [PATCH] ecryptfs:...
271
272
273
  out:
  	return rc;
  }
778aeb42a   Tyler Hicks   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   Michael Halcrow   [PATCH] ecryptfs:...
305
  /**
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
306
   * ecryptfs_lookup_interpose - Dentry interposition for a lookup
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
307
   */
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
308
  static int ecryptfs_lookup_interpose(struct dentry *dentry,
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
309
  				     struct dentry *lower_dentry,
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
310
  				     struct inode *dir_inode)
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
311
  {
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
312
313
  	struct inode *inode, *lower_inode = lower_dentry->d_inode;
  	struct ecryptfs_dentry_info *dentry_info;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
314
  	struct vfsmount *lower_mnt;
778aeb42a   Tyler Hicks   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   Nick Piggin   fs: dcache scale ...
319
  	BUG_ON(!lower_dentry->d_count);
778aeb42a   Tyler Hicks   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   Michael Halcrow   eCryptfs: Filenam...
324
325
326
327
  		printk(KERN_ERR "%s: Out of memory whilst attempting "
  		       "to allocate ecryptfs_dentry_info struct
  ",
  			__func__);
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
328
329
330
331
  		dput(lower_dentry);
  		mntput(lower_mnt);
  		d_drop(dentry);
  		return -ENOMEM;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
332
  	}
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
333
334
  	ecryptfs_set_dentry_lower(dentry, lower_dentry);
  	ecryptfs_set_dentry_lower_mnt(dentry, lower_mnt);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
335
336
  	if (!lower_dentry->d_inode) {
  		/* We want to add because we couldn't find in lower */
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
337
338
  		d_add(dentry, NULL);
  		return 0;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
339
  	}
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
340
  	inode = __ecryptfs_get_inode(lower_inode, dir_inode->i_sb);
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
341
  	if (IS_ERR(inode)) {
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
342
343
344
345
  		printk(KERN_ERR "%s: Error interposing; rc = [%ld]
  ",
  		       __func__, PTR_ERR(inode));
  		return PTR_ERR(inode);
391b52f98   Michael Halcrow   eCryptfs: Make al...
346
  	}
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
347
348
  	if (S_ISREG(inode->i_mode)) {
  		rc = ecryptfs_i_size_read(dentry, inode);
dd2a3b7ad   Michael Halcrow   [PATCH] eCryptfs:...
349
  		if (rc) {
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
350
351
  			make_bad_inode(inode);
  			return rc;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
352
  		}
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
353
  	}
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
354

3b06b3ebf   Tyler Hicks   eCryptfs: Fix new...
355
356
  	if (inode->i_state & I_NEW)
  		unlock_new_inode(inode);
778aeb42a   Tyler Hicks   eCryptfs: Cleanup...
357
  	d_add(dentry, inode);
addd65ad8   Michael Halcrow   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   Michael Halcrow   eCryptfs: Fix dat...
375
  	size_t encrypted_and_encoded_name_size;
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
376
  	struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL;
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
377
378
  	struct dentry *lower_dir_dentry, *lower_dentry;
  	int rc = 0;
addd65ad8   Michael Halcrow   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   Tyler Hicks   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   Michael Halcrow   eCryptfs: Filenam...
391
392
  	if (IS_ERR(lower_dentry)) {
  		rc = PTR_ERR(lower_dentry);
8787c7a3e   Tyler Hicks   eCryptfs: Revert ...
393
  		ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
9f37622f8   Tyler Hicks   eCryptfs: Turn lo...
394
395
396
  				"[%d] on lower_dentry = [%s]
  ", __func__, rc,
  				encrypted_and_encoded_name);
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
397
398
399
  		goto out_d_drop;
  	}
  	if (lower_dentry->d_inode)
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
400
  		goto interpose;
2aac0cf88   Tyler Hicks   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   Tyler Hicks   eCryptfs: Cleanup...
405
  		goto interpose;
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
406
407
408
  	dput(lower_dentry);
  	rc = ecryptfs_encrypt_and_encode_filename(
  		&encrypted_and_encoded_name, &encrypted_and_encoded_name_size,
2aac0cf88   Tyler Hicks   eCryptfs: NULL cr...
409
  		NULL, mount_crypt_stat, ecryptfs_dentry->d_name.name,
addd65ad8   Michael Halcrow   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   Tyler Hicks   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   Michael Halcrow   eCryptfs: Filenam...
422
423
  	if (IS_ERR(lower_dentry)) {
  		rc = PTR_ERR(lower_dentry);
8787c7a3e   Tyler Hicks   eCryptfs: Revert ...
424
  		ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
9f37622f8   Tyler Hicks   eCryptfs: Turn lo...
425
426
427
  				"[%d] on lower_dentry = [%s]
  ", __func__, rc,
  				encrypted_and_encoded_name);
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
428
429
  		goto out_d_drop;
  	}
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
430
431
432
  interpose:
  	rc = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry,
  				       ecryptfs_dir_inode);
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
433
434
435
  	goto out;
  out_d_drop:
  	d_drop(ecryptfs_dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
436
  out:
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
437
  	kfree(encrypted_and_encoded_name);
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Cleanup...
460
  	rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
461
462
  	if (rc)
  		goto out_lock;
3a8380c07   Tyler Hicks   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   Miklos Szeredi   filesystems: add ...
465
466
  	set_nlink(old_dentry->d_inode,
  		  ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink);
237fead61   Michael Halcrow   [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   Michael Halcrow   [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   Miklos Szeredi   ecryptfs: clean u...
480
  	struct dentry *lower_dir_dentry;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
481

9c2d20566   Tyler Hicks   eCryptfs: Prevent...
482
  	dget(lower_dentry);
8dc4e3736   Miklos Szeredi   ecryptfs: clean u...
483
  	lower_dir_dentry = lock_parent(lower_dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
484
485
  	rc = vfs_unlink(lower_dir_inode, lower_dentry);
  	if (rc) {
ae56fb163   Michael Halcrow   [PATCH] eCryptfs:...
486
487
  		printk(KERN_ERR "Error in vfs_unlink; rc = [%d]
  ", rc);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
488
489
  		goto out_unlock;
  	}
0cc72dc7f   Josef "Jeff" Sipek   [PATCH] eCryptfs:...
490
  	fsstack_copy_attr_times(dir, lower_dir_inode);
bfe868486   Miklos Szeredi   filesystems: add ...
491
492
  	set_nlink(dentry->d_inode,
  		  ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
493
  	dentry->d_inode->i_ctime = dir->i_ctime;
caeeeecfd   Michael Halcrow   eCryptfs: fix den...
494
  	d_drop(dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
495
  out_unlock:
8dc4e3736   Miklos Szeredi   ecryptfs: clean u...
496
  	unlock_dir(lower_dir_dentry);
9c2d20566   Tyler Hicks   eCryptfs: Prevent...
497
  	dput(lower_dentry);
237fead61   Michael Halcrow   [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   Michael Halcrow   [PATCH] ecryptfs:...
507
  	char *encoded_symname;
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
508
509
  	size_t encoded_symlen;
  	struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
510
511
512
513
  
  	lower_dentry = ecryptfs_dentry_to_lower(dentry);
  	dget(lower_dentry);
  	lower_dir_dentry = lock_parent(lower_dentry);
addd65ad8   Michael Halcrow   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   Michael Halcrow   [PATCH] ecryptfs:...
522
  		goto out_lock;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
523
  	rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
db2e747b1   Miklos Szeredi   [patch 5/5] vfs: ...
524
  			 encoded_symname);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
525
526
527
  	kfree(encoded_symname);
  	if (rc || !lower_dentry->d_inode)
  		goto out_lock;
5ccf92037   Tyler Hicks   eCryptfs: Cleanup...
528
  	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
529
530
  	if (rc)
  		goto out_lock;
0cc72dc7f   Josef "Jeff" Sipek   [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   Michael Halcrow   [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   Al Viro   switch vfs_mkdir(...
540
  static int ecryptfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Cleanup...
551
  	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
552
553
  	if (rc)
  		goto out;
0cc72dc7f   Josef "Jeff" Sipek   [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   Miklos Szeredi   filesystems: add ...
556
  	set_nlink(dir, lower_dir_dentry->d_inode->i_nlink);
237fead61   Michael Halcrow   [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   Michael Halcrow   [PATCH] ecryptfs:...
566
  	struct dentry *lower_dentry;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
567
  	struct dentry *lower_dir_dentry;
45ec4abab   Michael Halcrow   [PATCH] eCryptfs:...
568
  	int rc;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
569
570
  
  	lower_dentry = ecryptfs_dentry_to_lower(dentry);
45ec4abab   Michael Halcrow   [PATCH] eCryptfs:...
571
  	dget(dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
572
  	lower_dir_dentry = lock_parent(lower_dentry);
45ec4abab   Michael Halcrow   [PATCH] eCryptfs:...
573
  	dget(lower_dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
574
  	rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
45ec4abab   Michael Halcrow   [PATCH] eCryptfs:...
575
  	dput(lower_dentry);
07850552b   Tyler Hicks   eCryptfs: Clear i...
576
577
  	if (!rc && dentry->d_inode)
  		clear_nlink(dentry->d_inode);
0cc72dc7f   Josef "Jeff" Sipek   [PATCH] eCryptfs:...
578
  	fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
bfe868486   Miklos Szeredi   filesystems: add ...
579
  	set_nlink(dir, lower_dir_dentry->d_inode->i_nlink);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
580
581
582
  	unlock_dir(lower_dir_dentry);
  	if (!rc)
  		d_drop(dentry);
45ec4abab   Michael Halcrow   [PATCH] eCryptfs:...
583
  	dput(dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
584
585
586
587
  	return rc;
  }
  
  static int
1a67aafb5   Al Viro   switch ->mknod() ...
588
  ecryptfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Cleanup...
599
  	rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
600
601
  	if (rc)
  		goto out;
0cc72dc7f   Josef "Jeff" Sipek   [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   Michael Halcrow   [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   Erez Zadok   ecryptfs: don't i...
620
  	struct dentry *trap = NULL;
237fead61   Michael Halcrow   [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   Erez Zadok   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   Michael Halcrow   [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   Erez Zadok   fsstack/ecryptfs:...
643
  	fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
644
  	if (new_dir != old_dir)
9afa2fb6c   Erez Zadok   fsstack/ecryptfs:...
645
  		fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
646
647
  out_lock:
  	unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
dd55c8985   Tyler Hicks   eCryptfs: dput de...
648
649
  	dput(lower_new_dir_dentry);
  	dput(lower_old_dir_dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
650
651
652
653
  	dput(lower_new_dentry);
  	dput(lower_old_dentry);
  	return rc;
  }
3a60a1686   Tyler Hicks   eCryptfs: Decrypt...
654
655
  static int ecryptfs_readlink_lower(struct dentry *dentry, char **buf,
  				   size_t *bufsiz)
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
656
  {
3a60a1686   Tyler Hicks   eCryptfs: Decrypt...
657
  	struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
658
  	char *lower_buf;
3a60a1686   Tyler Hicks   eCryptfs: Decrypt...
659
  	size_t lower_bufsiz = PATH_MAX;
addd65ad8   Michael Halcrow   eCryptfs: Filenam...
660
661
  	mm_segment_t old_fs;
  	int rc;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
662

3a6b42cad   Tyler Hicks   eCryptfs: Larger ...
663
  	lower_buf = kmalloc(lower_bufsiz, GFP_KERNEL);
3a60a1686   Tyler Hicks   eCryptfs: Decrypt...
664
  	if (!lower_buf) {
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
665
666
667
668
669
  		rc = -ENOMEM;
  		goto out;
  	}
  	old_fs = get_fs();
  	set_fs(get_ds());
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
670
671
  	rc = lower_dentry->d_inode->i_op->readlink(lower_dentry,
  						   (char __user *)lower_buf,
3a6b42cad   Tyler Hicks   eCryptfs: Larger ...
672
  						   lower_bufsiz);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
673
  	set_fs(old_fs);
3a60a1686   Tyler Hicks   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   Michael Halcrow   [PATCH] ecryptfs:...
680
  	kfree(lower_buf);
3a60a1686   Tyler Hicks   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   Michael Halcrow   [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   OGAWA Hirofumi   ecryptfs: Fix ref...
712
  		buf = ERR_PTR(-ENOMEM);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
713
714
715
716
  		goto out;
  	}
  	old_fs = get_fs();
  	set_fs(get_ds());
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
717
  	rc = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
718
  	set_fs(old_fs);
806892e9e   OGAWA Hirofumi   ecryptfs: Fix ref...
719
720
721
722
  	if (rc < 0) {
  		kfree(buf);
  		buf = ERR_PTR(rc);
  	} else
a17d5232d   Duane Griffin   eCryptfs: check r...
723
  		buf[rc] = '\0';
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
724
  out:
806892e9e   OGAWA Hirofumi   ecryptfs: Fix ref...
725
726
  	nd_set_link(nd, buf);
  	return NULL;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
727
728
729
730
731
  }
  
  static void
  ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr)
  {
806892e9e   OGAWA Hirofumi   ecryptfs: Fix ref...
732
733
734
735
736
  	char *buf = nd_get_link(nd);
  	if (!IS_ERR(buf)) {
  		/* Free the char* */
  		kfree(buf);
  	}
237fead61   Michael Halcrow   [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   Michael Halcrow   eCryptfs: track h...
744
   * Calculate the required size of the lower file based on the
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Fix met...
755
  	lower_size = ecryptfs_lower_header_size(crypt_stat);
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Use not...
768
   * truncate_upper
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
769
   * @dentry: The ecryptfs layer dentry
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
770
771
   * @ia: Address of the ecryptfs inode's attributes
   * @lower_ia: Address of the lower inode's attributes
237fead61   Michael Halcrow   [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   Tyler Hicks   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   Michael Halcrow   [PATCH] ecryptfs:...
780
781
782
   *
   * Returns zero on success; non-zero otherwise
   */
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
783
784
  static int truncate_upper(struct dentry *dentry, struct iattr *ia,
  			  struct iattr *lower_ia)
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
785
786
787
  {
  	int rc = 0;
  	struct inode *inode = dentry->d_inode;
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Use not...
792
793
  	if (unlikely((ia->ia_size == i_size))) {
  		lower_ia->ia_valid &= ~ATTR_SIZE;
332ab16f8   Tyler Hicks   eCryptfs: Add ref...
794
  		return 0;
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
795
  	}
3b06b3ebf   Tyler Hicks   eCryptfs: Fix new...
796
  	rc = ecryptfs_get_lower_file(dentry, inode);
332ab16f8   Tyler Hicks   eCryptfs: Add ref...
797
798
  	if (rc)
  		return rc;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
799
  	crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
800
  	/* Switch on growing or shrinking file */
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
801
  	if (ia->ia_size > i_size) {
2ed92554a   Michael Halcrow   eCryptfs: make op...
802
  		char zero[] = { 0x00 };
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
803
  		lower_ia->ia_valid &= ~ATTR_SIZE;
2ed92554a   Michael Halcrow   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   Al Viro   switch ecryptfs_w...
808
  		rc = ecryptfs_write(inode, zero,
5f3ef64f4   Tyler Hicks   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   Michael Halcrow   eCryptfs: make op...
814
815
  		 * PAGE_CACHE_SIZE with zeros. */
  		size_t num_zeros = (PAGE_CACHE_SIZE
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
816
  				    - (ia->ia_size & ~PAGE_CACHE_MASK));
2ed92554a   Michael Halcrow   eCryptfs: make op...
817

2c27c65ed   Christoph Hellwig   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   Tyler Hicks   eCryptfs: Fix dat...
829
  		if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
2c27c65ed   Christoph Hellwig   check ATTR_SIZE c...
830
  			truncate_setsize(inode, ia->ia_size);
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
831
832
  			lower_ia->ia_size = ia->ia_size;
  			lower_ia->ia_valid |= ATTR_SIZE;
48c1e44ac   Al Viro   switch ecryptfs_w...
833
  			goto out;
13a791b4e   Tyler Hicks   eCryptfs: Fix dat...
834
  		}
2ed92554a   Michael Halcrow   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   Al Viro   switch ecryptfs_w...
841
  				goto out;
2ed92554a   Michael Halcrow   eCryptfs: make op...
842
  			}
48c1e44ac   Al Viro   switch ecryptfs_w...
843
  			rc = ecryptfs_write(inode, zeros_virt,
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
844
  					    ia->ia_size, num_zeros);
2ed92554a   Michael Halcrow   eCryptfs: make op...
845
  			kfree(zeros_virt);
5dda6992a   Michael Halcrow   eCryptfs: remove ...
846
  			if (rc) {
240e2df5c   Michael Halcrow   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   Al Viro   switch ecryptfs_w...
851
  				goto out;
240e2df5c   Michael Halcrow   eCryptfs: fix wri...
852
853
  			}
  		}
2c27c65ed   Christoph Hellwig   check ATTR_SIZE c...
854
  		truncate_setsize(inode, ia->ia_size);
0216f7f79   Michael Halcrow   eCryptfs: replace...
855
  		rc = ecryptfs_write_inode_size_to_metadata(inode);
dd2a3b7ad   Michael Halcrow   [PATCH] eCryptfs:...
856
857
858
859
860
  		if (rc) {
  			printk(KERN_ERR	"Problem with "
  			       "ecryptfs_write_inode_size_to_metadata; "
  			       "rc = [%d]
  ", rc);
48c1e44ac   Al Viro   switch ecryptfs_w...
861
  			goto out;
dd2a3b7ad   Michael Halcrow   [PATCH] eCryptfs:...
862
  		}
237fead61   Michael Halcrow   [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   Tyler Hicks   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   Michael Halcrow   [PATCH] ecryptfs:...
874
  	}
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
875
  out:
332ab16f8   Tyler Hicks   eCryptfs: Add ref...
876
  	ecryptfs_put_lower_file(inode);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
877
878
  	return rc;
  }
5f3ef64f4   Tyler Hicks   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   Michael Halcrow   [PATCH] ecryptfs:...
905
  static int
10556cb21   Al Viro   ->permission() sa...
906
  ecryptfs_permission(struct inode *inode, int mask)
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
907
  {
f419a2e3b   Al Viro   [PATCH] kill name...
908
  	return inode_permission(ecryptfs_inode_to_lower(inode), mask);
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Use not...
927
  	struct iattr lower_ia;
237fead61   Michael Halcrow   [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   Michael Halcrow   eCryptfs: initial...
933
934
  	if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED))
  		ecryptfs_init_crypt_stat(crypt_stat);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
935
936
  	inode = dentry->d_inode;
  	lower_inode = ecryptfs_inode_to_lower(inode);
e10f281bc   Michael Halcrow   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   Michael Halcrow   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   Michael Halcrow   eCryptfs: initial...
944
  		struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
e10f281bc   Michael Halcrow   eCryptfs: initial...
945

e10f281bc   Michael Halcrow   eCryptfs: initial...
946
947
  		mount_crypt_stat = &ecryptfs_superblock_to_private(
  			dentry->d_sb)->mount_crypt_stat;
3b06b3ebf   Tyler Hicks   eCryptfs: Fix new...
948
  		rc = ecryptfs_get_lower_file(dentry, inode);
332ab16f8   Tyler Hicks   eCryptfs: Add ref...
949
950
951
952
  		if (rc) {
  			mutex_unlock(&crypt_stat->cs_mutex);
  			goto out;
  		}
d7cdc5feb   Michael Halcrow   eCryptfs: update ...
953
  		rc = ecryptfs_read_metadata(dentry);
332ab16f8   Tyler Hicks   eCryptfs: Add ref...
954
  		ecryptfs_put_lower_file(inode);
5dda6992a   Michael Halcrow   eCryptfs: remove ...
955
  		if (rc) {
e10f281bc   Michael Halcrow   eCryptfs: initial...
956
957
958
  			if (!(mount_crypt_stat->flags
  			      & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
  				rc = -EIO;
25bd81740   Michael Halcrow   eCryptfs: Minor f...
959
  				printk(KERN_WARNING "Either the lower file "
e10f281bc   Michael Halcrow   eCryptfs: initial...
960
  				       "is not in a valid eCryptfs format, "
25bd81740   Michael Halcrow   eCryptfs: Minor f...
961
962
  				       "or the key could not be retrieved. "
  				       "Plaintext passthrough mode is not "
e10f281bc   Michael Halcrow   eCryptfs: initial...
963
964
  				       "enabled; returning -EIO
  ");
e10f281bc   Michael Halcrow   eCryptfs: initial...
965
  				mutex_unlock(&crypt_stat->cs_mutex);
e10f281bc   Michael Halcrow   eCryptfs: initial...
966
967
968
  				goto out;
  			}
  			rc = 0;
3aeb86ea4   Tyler Hicks   eCryptfs: Handle ...
969
970
  			crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED
  					       | ECRYPTFS_ENCRYPTED);
e10f281bc   Michael Halcrow   eCryptfs: initial...
971
  		}
e10f281bc   Michael Halcrow   eCryptfs: initial...
972
973
  	}
  	mutex_unlock(&crypt_stat->cs_mutex);
5be79de2e   Tyler Hicks   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   Tyler Hicks   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   Michael Halcrow   [PATCH] ecryptfs:...
983
  	if (ia->ia_valid & ATTR_SIZE) {
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
984
  		rc = truncate_upper(dentry, ia, &lower_ia);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
985
986
987
  		if (rc < 0)
  			goto out;
  	}
1ac564eca   Jeff Layton   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   Tyler Hicks   eCryptfs: Use not...
993
994
  	if (lower_ia.ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
  		lower_ia.ia_valid &= ~ATTR_MODE;
1ac564eca   Jeff Layton   ecryptfs: allow l...
995

9c3580aa5   Miklos Szeredi   ecryptfs: add mis...
996
  	mutex_lock(&lower_dentry->d_inode->i_mutex);
5f3ef64f4   Tyler Hicks   eCryptfs: Use not...
997
  	rc = notify_change(lower_dentry, &lower_ia);
9c3580aa5   Miklos Szeredi   ecryptfs: add mis...
998
  	mutex_unlock(&lower_dentry->d_inode->i_mutex);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
999
  out:
9afa2fb6c   Erez Zadok   fsstack/ecryptfs:...
1000
  	fsstack_copy_attr_all(inode, lower_inode);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
1001
1002
  	return rc;
  }
3a60a1686   Tyler Hicks   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   Tyler Hicks   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   Tyler Hicks   eCryptfs: Copy up...
1033
1034
  		fsstack_copy_attr_all(dentry->d_inode,
  				      ecryptfs_inode_to_lower(dentry->d_inode));
f8f484d1b   Tyler Hicks   eCryptfs: Add get...
1035
1036
1037
1038
1039
  		generic_fillattr(dentry->d_inode, stat);
  		stat->blocks = lower_stat.blocks;
  	}
  	return rc;
  }
dd2a3b7ad   Michael Halcrow   [PATCH] eCryptfs:...
1040
  int
237fead61   Michael Halcrow   [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   Christian Pulvermacher   ecryptfs: fix err...
1049
  		rc = -EOPNOTSUPP;
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
1050
1051
  		goto out;
  	}
48b512e68   Roberto Sassu   ecryptfs: call vf...
1052
1053
  
  	rc = vfs_setxattr(lower_dentry, name, value, size, flags);
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
1054
1055
1056
  out:
  	return rc;
  }
dd2a3b7ad   Michael Halcrow   [PATCH] eCryptfs:...
1057
  ssize_t
d7cdc5feb   Michael Halcrow   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   Christian Pulvermacher   ecryptfs: fix err...
1064
  		rc = -EOPNOTSUPP;
d7cdc5feb   Michael Halcrow   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   Adrian Bunk   fs/ecryptfs/: pos...
1074
  static ssize_t
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
1075
1076
1077
  ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
  		  size_t size)
  {
2ed92554a   Michael Halcrow   eCryptfs: make op...
1078
1079
  	return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), name,
  				       value, size);
237fead61   Michael Halcrow   [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   Christian Pulvermacher   ecryptfs: fix err...
1090
  		rc = -EOPNOTSUPP;
237fead61   Michael Halcrow   [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   Christian Pulvermacher   ecryptfs: fix err...
1107
  		rc = -EOPNOTSUPP;
237fead61   Michael Halcrow   [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   Arjan van de Ven   [PATCH] mark stru...
1116
  const struct inode_operations ecryptfs_symlink_iops = {
237fead61   Michael Halcrow   [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   Tyler Hicks   eCryptfs: Decrypt...
1122
  	.getattr = ecryptfs_getattr_link,
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
1123
1124
1125
1126
1127
  	.setxattr = ecryptfs_setxattr,
  	.getxattr = ecryptfs_getxattr,
  	.listxattr = ecryptfs_listxattr,
  	.removexattr = ecryptfs_removexattr
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
1128
  const struct inode_operations ecryptfs_dir_iops = {
237fead61   Michael Halcrow   [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   Arjan van de Ven   [PATCH] mark stru...
1145
  const struct inode_operations ecryptfs_main_iops = {
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
1146
1147
  	.permission = ecryptfs_permission,
  	.setattr = ecryptfs_setattr,
f8f484d1b   Tyler Hicks   eCryptfs: Add get...
1148
  	.getattr = ecryptfs_getattr,
237fead61   Michael Halcrow   [PATCH] ecryptfs:...
1149
1150
1151
1152
1153
  	.setxattr = ecryptfs_setxattr,
  	.getxattr = ecryptfs_getxattr,
  	.listxattr = ecryptfs_listxattr,
  	.removexattr = ecryptfs_removexattr
  };