eCryptfs: Add reference counting to lower files

For any given lower inode, eCryptfs keeps only one lower file open and
multiplexes all eCryptfs file operations through that lower file. The
lower file was considered "persistent" and stayed open from the first
lookup through the lifetime of the inode.

This patch keeps the notion of a single, per-inode lower file, but adds
reference counting around the lower file so that it is closed when not
currently in use. If the reference count is at 0 when an operation (such
as open, create, etc.) needs to use the lower file, a new lower file is
opened. Since the file is no longer persistent, all references to the
term persistent file are changed to lower file.

Locking is added around the sections of code that opens the lower file
and assign the pointer in the inode info, as well as the code the fputs
the lower file when all eCryptfs users are done with it.

This patch is needed to fix issues, when mounted on top of the NFSv3
client, where the lower file is left silly renamed until the eCryptfs
inode is destroyed.

Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>

+93 -60
+4 -1
fs/ecryptfs/ecryptfs_kernel.h
··· 295 struct ecryptfs_inode_info { 296 struct inode vfs_inode; 297 struct inode *wii_inode; 298 struct file *lower_file; 299 struct ecryptfs_crypt_stat crypt_stat; 300 }; ··· 759 struct dentry *lower_dentry, 760 struct vfsmount *lower_mnt, 761 const struct cred *cred); 762 - int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); 763 int 764 ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, 765 size_t *packet_size,
··· 295 struct ecryptfs_inode_info { 296 struct inode vfs_inode; 297 struct inode *wii_inode; 298 + struct mutex lower_file_mutex; 299 + atomic_t lower_file_count; 300 struct file *lower_file; 301 struct ecryptfs_crypt_stat crypt_stat; 302 }; ··· 757 struct dentry *lower_dentry, 758 struct vfsmount *lower_mnt, 759 const struct cred *cred); 760 + int ecryptfs_get_lower_file(struct dentry *ecryptfs_dentry); 761 + void ecryptfs_put_lower_file(struct inode *inode); 762 int 763 ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, 764 size_t *packet_size,
+10 -12
fs/ecryptfs/file.c
··· 191 | ECRYPTFS_ENCRYPTED); 192 } 193 mutex_unlock(&crypt_stat->cs_mutex); 194 - rc = ecryptfs_init_persistent_file(ecryptfs_dentry); 195 if (rc) { 196 printk(KERN_ERR "%s: Error attempting to initialize " 197 - "the persistent file for the dentry with name " 198 "[%s]; rc = [%d]\n", __func__, 199 ecryptfs_dentry->d_name.name, rc); 200 goto out_free; ··· 202 if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE) 203 == O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) { 204 rc = -EPERM; 205 - printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " 206 "file must hence be opened RO\n", __func__); 207 - goto out_free; 208 } 209 ecryptfs_set_file_lower( 210 file, ecryptfs_inode_to_private(inode)->lower_file); ··· 232 "Plaintext passthrough mode is not " 233 "enabled; returning -EIO\n"); 234 mutex_unlock(&crypt_stat->cs_mutex); 235 - goto out_free; 236 } 237 rc = 0; 238 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); ··· 245 "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, 246 (unsigned long long)i_size_read(inode)); 247 goto out; 248 out_free: 249 kmem_cache_free(ecryptfs_file_info_cache, 250 ecryptfs_file_to_private(file)); ··· 256 257 static int ecryptfs_flush(struct file *file, fl_owner_t td) 258 { 259 - int rc = 0; 260 - struct file *lower_file = NULL; 261 - 262 - lower_file = ecryptfs_file_to_lower(file); 263 - if (lower_file->f_op && lower_file->f_op->flush) 264 - rc = lower_file->f_op->flush(lower_file, td); 265 - return rc; 266 } 267 268 static int ecryptfs_release(struct inode *inode, struct file *file) 269 { 270 kmem_cache_free(ecryptfs_file_info_cache, 271 ecryptfs_file_to_private(file)); 272 return 0;
··· 191 | ECRYPTFS_ENCRYPTED); 192 } 193 mutex_unlock(&crypt_stat->cs_mutex); 194 + rc = ecryptfs_get_lower_file(ecryptfs_dentry); 195 if (rc) { 196 printk(KERN_ERR "%s: Error attempting to initialize " 197 + "the lower file for the dentry with name " 198 "[%s]; rc = [%d]\n", __func__, 199 ecryptfs_dentry->d_name.name, rc); 200 goto out_free; ··· 202 if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE) 203 == O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) { 204 rc = -EPERM; 205 + printk(KERN_WARNING "%s: Lower file is RO; eCryptfs " 206 "file must hence be opened RO\n", __func__); 207 + goto out_put; 208 } 209 ecryptfs_set_file_lower( 210 file, ecryptfs_inode_to_private(inode)->lower_file); ··· 232 "Plaintext passthrough mode is not " 233 "enabled; returning -EIO\n"); 234 mutex_unlock(&crypt_stat->cs_mutex); 235 + goto out_put; 236 } 237 rc = 0; 238 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); ··· 245 "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, 246 (unsigned long long)i_size_read(inode)); 247 goto out; 248 + out_put: 249 + ecryptfs_put_lower_file(inode); 250 out_free: 251 kmem_cache_free(ecryptfs_file_info_cache, 252 ecryptfs_file_to_private(file)); ··· 254 255 static int ecryptfs_flush(struct file *file, fl_owner_t td) 256 { 257 + return file->f_mode & FMODE_WRITE 258 + ? filemap_write_and_wait(file->f_mapping) : 0; 259 } 260 261 static int ecryptfs_release(struct inode *inode, struct file *file) 262 { 263 + ecryptfs_put_lower_file(inode); 264 kmem_cache_free(ecryptfs_file_info_cache, 265 ecryptfs_file_to_private(file)); 266 return 0;
+21 -9
fs/ecryptfs/inode.c
··· 168 "context; rc = [%d]\n", rc); 169 goto out; 170 } 171 - rc = ecryptfs_init_persistent_file(ecryptfs_dentry); 172 if (rc) { 173 printk(KERN_ERR "%s: Error attempting to initialize " 174 - "the persistent file for the dentry with name " 175 "[%s]; rc = [%d]\n", __func__, 176 ecryptfs_dentry->d_name.name, rc); 177 goto out; 178 } 179 rc = ecryptfs_write_metadata(ecryptfs_dentry); 180 - if (rc) { 181 printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); 182 - goto out; 183 - } 184 out: 185 return rc; 186 } ··· 229 struct ecryptfs_crypt_stat *crypt_stat; 230 char *page_virt = NULL; 231 u64 file_size; 232 - int rc = 0; 233 234 lower_dir_dentry = lower_dentry->d_parent; 235 lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( ··· 276 rc = -ENOMEM; 277 goto out; 278 } 279 - rc = ecryptfs_init_persistent_file(ecryptfs_dentry); 280 if (rc) { 281 printk(KERN_ERR "%s: Error attempting to initialize " 282 - "the persistent file for the dentry with name " 283 "[%s]; rc = [%d]\n", __func__, 284 ecryptfs_dentry->d_name.name, rc); 285 goto out_free_kmem; 286 } 287 crypt_stat = &ecryptfs_inode_to_private( 288 ecryptfs_dentry->d_inode)->crypt_stat; 289 /* TODO: lock for crypt_stat comparison */ ··· 322 mntput(lower_mnt); 323 d_drop(ecryptfs_dentry); 324 out: 325 return rc; 326 } 327 ··· 759 760 if (unlikely((ia->ia_size == i_size))) { 761 lower_ia->ia_valid &= ~ATTR_SIZE; 762 - goto out; 763 } 764 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; 765 /* Switch on growing or shrinking file */ 766 if (ia->ia_size > i_size) { ··· 841 lower_ia->ia_valid &= ~ATTR_SIZE; 842 } 843 out: 844 return rc; 845 } 846 ··· 917 918 mount_crypt_stat = &ecryptfs_superblock_to_private( 919 dentry->d_sb)->mount_crypt_stat; 920 rc = ecryptfs_read_metadata(dentry); 921 if (rc) { 922 if (!(mount_crypt_stat->flags 923 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
··· 168 "context; rc = [%d]\n", rc); 169 goto out; 170 } 171 + rc = ecryptfs_get_lower_file(ecryptfs_dentry); 172 if (rc) { 173 printk(KERN_ERR "%s: Error attempting to initialize " 174 + "the lower file for the dentry with name " 175 "[%s]; rc = [%d]\n", __func__, 176 ecryptfs_dentry->d_name.name, rc); 177 goto out; 178 } 179 rc = ecryptfs_write_metadata(ecryptfs_dentry); 180 + if (rc) 181 printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); 182 + ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); 183 out: 184 return rc; 185 } ··· 230 struct ecryptfs_crypt_stat *crypt_stat; 231 char *page_virt = NULL; 232 u64 file_size; 233 + int put_lower = 0, rc = 0; 234 235 lower_dir_dentry = lower_dentry->d_parent; 236 lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( ··· 277 rc = -ENOMEM; 278 goto out; 279 } 280 + rc = ecryptfs_get_lower_file(ecryptfs_dentry); 281 if (rc) { 282 printk(KERN_ERR "%s: Error attempting to initialize " 283 + "the lower file for the dentry with name " 284 "[%s]; rc = [%d]\n", __func__, 285 ecryptfs_dentry->d_name.name, rc); 286 goto out_free_kmem; 287 } 288 + put_lower = 1; 289 crypt_stat = &ecryptfs_inode_to_private( 290 ecryptfs_dentry->d_inode)->crypt_stat; 291 /* TODO: lock for crypt_stat comparison */ ··· 322 mntput(lower_mnt); 323 d_drop(ecryptfs_dentry); 324 out: 325 + if (put_lower) 326 + ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); 327 return rc; 328 } 329 ··· 757 758 if (unlikely((ia->ia_size == i_size))) { 759 lower_ia->ia_valid &= ~ATTR_SIZE; 760 + return 0; 761 } 762 + rc = ecryptfs_get_lower_file(dentry); 763 + if (rc) 764 + return rc; 765 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; 766 /* Switch on growing or shrinking file */ 767 if (ia->ia_size > i_size) { ··· 836 lower_ia->ia_valid &= ~ATTR_SIZE; 837 } 838 out: 839 + ecryptfs_put_lower_file(inode); 840 return rc; 841 } 842 ··· 911 912 mount_crypt_stat = &ecryptfs_superblock_to_private( 913 dentry->d_sb)->mount_crypt_stat; 914 + rc = ecryptfs_get_lower_file(dentry); 915 + if (rc) { 916 + mutex_unlock(&crypt_stat->cs_mutex); 917 + goto out; 918 + } 919 rc = ecryptfs_read_metadata(dentry); 920 + ecryptfs_put_lower_file(inode); 921 if (rc) { 922 if (!(mount_crypt_stat->flags 923 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
+3 -3
fs/ecryptfs/kthread.c
··· 44 * @ignored: ignored 45 * 46 * The eCryptfs kernel thread that has the responsibility of getting 47 - * the lower persistent file with RW permissions. 48 * 49 * Returns zero on success; non-zero otherwise 50 */ ··· 141 int rc = 0; 142 143 /* Corresponding dput() and mntput() are done when the 144 - * persistent file is fput() when the eCryptfs inode is 145 - * destroyed. */ 146 dget(lower_dentry); 147 mntget(lower_mnt); 148 flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
··· 44 * @ignored: ignored 45 * 46 * The eCryptfs kernel thread that has the responsibility of getting 47 + * the lower file with RW permissions. 48 * 49 * Returns zero on success; non-zero otherwise 50 */ ··· 141 int rc = 0; 142 143 /* Corresponding dput() and mntput() are done when the 144 + * lower file is fput() when all eCryptfs files for the inode are 145 + * released. */ 146 dget(lower_dentry); 147 mntget(lower_mnt); 148 flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR;
+51 -23
fs/ecryptfs/main.c
··· 96 } 97 98 /** 99 - * ecryptfs_init_persistent_file 100 * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with 101 * the lower dentry and the lower mount set 102 * ··· 104 * inode. All I/O operations to the lower inode occur through that 105 * file. When the first eCryptfs dentry that interposes with the first 106 * lower dentry for that inode is created, this function creates the 107 - * persistent file struct and associates it with the eCryptfs 108 - * inode. When the eCryptfs inode is destroyed, the file is closed. 109 * 110 - * The persistent file will be opened with read/write permissions, if 111 * possible. Otherwise, it is opened read-only. 112 * 113 - * This function does nothing if a lower persistent file is already 114 * associated with the eCryptfs inode. 115 * 116 * Returns zero on success; non-zero otherwise 117 */ 118 - int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) 119 { 120 const struct cred *cred = current_cred(); 121 - struct ecryptfs_inode_info *inode_info = 122 - ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); 123 - int rc = 0; 124 125 - if (!inode_info->lower_file) { 126 - struct dentry *lower_dentry; 127 - struct vfsmount *lower_mnt = 128 - ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); 129 - 130 - lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 131 - rc = ecryptfs_privileged_open(&inode_info->lower_file, 132 - lower_dentry, lower_mnt, cred); 133 - if (rc) { 134 - printk(KERN_ERR "Error opening lower persistent file " 135 - "for lower_dentry [0x%p] and lower_mnt [0x%p]; " 136 - "rc = [%d]\n", lower_dentry, lower_mnt, rc); 137 - inode_info->lower_file = NULL; 138 - } 139 } 140 return rc; 141 } 142 143 static struct inode *ecryptfs_get_inode(struct inode *lower_inode,
··· 96 } 97 98 /** 99 + * ecryptfs_init_lower_file 100 * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with 101 * the lower dentry and the lower mount set 102 * ··· 104 * inode. All I/O operations to the lower inode occur through that 105 * file. When the first eCryptfs dentry that interposes with the first 106 * lower dentry for that inode is created, this function creates the 107 + * lower file struct and associates it with the eCryptfs 108 + * inode. When all eCryptfs files associated with the inode are released, the 109 + * file is closed. 110 * 111 + * The lower file will be opened with read/write permissions, if 112 * possible. Otherwise, it is opened read-only. 113 * 114 + * This function does nothing if a lower file is already 115 * associated with the eCryptfs inode. 116 * 117 * Returns zero on success; non-zero otherwise 118 */ 119 + static int ecryptfs_init_lower_file(struct dentry *dentry, 120 + struct file **lower_file) 121 { 122 const struct cred *cred = current_cred(); 123 + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); 124 + struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); 125 + int rc; 126 127 + rc = ecryptfs_privileged_open(lower_file, lower_dentry, lower_mnt, 128 + cred); 129 + if (rc) { 130 + printk(KERN_ERR "Error opening lower file " 131 + "for lower_dentry [0x%p] and lower_mnt [0x%p]; " 132 + "rc = [%d]\n", lower_dentry, lower_mnt, rc); 133 + (*lower_file) = NULL; 134 } 135 return rc; 136 + } 137 + 138 + int ecryptfs_get_lower_file(struct dentry *dentry) 139 + { 140 + struct ecryptfs_inode_info *inode_info = 141 + ecryptfs_inode_to_private(dentry->d_inode); 142 + int count, rc = 0; 143 + 144 + mutex_lock(&inode_info->lower_file_mutex); 145 + count = atomic_inc_return(&inode_info->lower_file_count); 146 + if (WARN_ON_ONCE(count < 1)) 147 + rc = -EINVAL; 148 + else if (count == 1) { 149 + rc = ecryptfs_init_lower_file(dentry, 150 + &inode_info->lower_file); 151 + if (rc) 152 + atomic_set(&inode_info->lower_file_count, 0); 153 + } 154 + mutex_unlock(&inode_info->lower_file_mutex); 155 + return rc; 156 + } 157 + 158 + void ecryptfs_put_lower_file(struct inode *inode) 159 + { 160 + struct ecryptfs_inode_info *inode_info; 161 + 162 + inode_info = ecryptfs_inode_to_private(inode); 163 + if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, 164 + &inode_info->lower_file_mutex)) { 165 + fput(inode_info->lower_file); 166 + inode_info->lower_file = NULL; 167 + mutex_unlock(&inode_info->lower_file_mutex); 168 + } 169 } 170 171 static struct inode *ecryptfs_get_inode(struct inode *lower_inode,
+4 -12
fs/ecryptfs/super.c
··· 55 if (unlikely(!inode_info)) 56 goto out; 57 ecryptfs_init_crypt_stat(&inode_info->crypt_stat); 58 inode_info->lower_file = NULL; 59 inode = &inode_info->vfs_inode; 60 out: ··· 79 * 80 * This is used during the final destruction of the inode. All 81 * allocation of memory related to the inode, including allocated 82 - * memory in the crypt_stat struct, will be released here. This 83 - * function also fput()'s the persistent file for the lower inode. 84 * There should be no chance that this deallocation will be missed. 85 */ 86 static void ecryptfs_destroy_inode(struct inode *inode) ··· 87 struct ecryptfs_inode_info *inode_info; 88 89 inode_info = ecryptfs_inode_to_private(inode); 90 - if (inode_info->lower_file) { 91 - struct dentry *lower_dentry = 92 - inode_info->lower_file->f_dentry; 93 - 94 - BUG_ON(!lower_dentry); 95 - if (lower_dentry->d_inode) { 96 - fput(inode_info->lower_file); 97 - inode_info->lower_file = NULL; 98 - } 99 - } 100 ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); 101 call_rcu(&inode->i_rcu, ecryptfs_i_callback); 102 }
··· 55 if (unlikely(!inode_info)) 56 goto out; 57 ecryptfs_init_crypt_stat(&inode_info->crypt_stat); 58 + mutex_init(&inode_info->lower_file_mutex); 59 + atomic_set(&inode_info->lower_file_count, 0); 60 inode_info->lower_file = NULL; 61 inode = &inode_info->vfs_inode; 62 out: ··· 77 * 78 * This is used during the final destruction of the inode. All 79 * allocation of memory related to the inode, including allocated 80 + * memory in the crypt_stat struct, will be released here. 81 * There should be no chance that this deallocation will be missed. 82 */ 83 static void ecryptfs_destroy_inode(struct inode *inode) ··· 86 struct ecryptfs_inode_info *inode_info; 87 88 inode_info = ecryptfs_inode_to_private(inode); 89 + BUG_ON(inode_info->lower_file); 90 ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); 91 call_rcu(&inode->i_rcu, ecryptfs_i_callback); 92 }