| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2011 Novell Inc. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms of the GNU General Public License version 2 as published by |
|---|
| 7 | | - * the Free Software Foundation. |
|---|
| 8 | 5 | */ |
|---|
| 9 | 6 | |
|---|
| 10 | 7 | #include <uapi/linux/magic.h> |
|---|
| .. | .. |
|---|
| 23 | 20 | MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); |
|---|
| 24 | 21 | MODULE_DESCRIPTION("Overlay filesystem"); |
|---|
| 25 | 22 | MODULE_LICENSE("GPL"); |
|---|
| 23 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 26 | 24 | |
|---|
| 27 | 25 | |
|---|
| 28 | 26 | struct ovl_dir_cache; |
|---|
| .. | .. |
|---|
| 31 | 29 | |
|---|
| 32 | 30 | static bool ovl_redirect_dir_def = IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_DIR); |
|---|
| 33 | 31 | module_param_named(redirect_dir, ovl_redirect_dir_def, bool, 0644); |
|---|
| 34 | | -MODULE_PARM_DESC(ovl_redirect_dir_def, |
|---|
| 32 | +MODULE_PARM_DESC(redirect_dir, |
|---|
| 35 | 33 | "Default to on or off for the redirect_dir feature"); |
|---|
| 36 | 34 | |
|---|
| 37 | 35 | static bool ovl_redirect_always_follow = |
|---|
| 38 | 36 | IS_ENABLED(CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW); |
|---|
| 39 | 37 | module_param_named(redirect_always_follow, ovl_redirect_always_follow, |
|---|
| 40 | 38 | bool, 0644); |
|---|
| 41 | | -MODULE_PARM_DESC(ovl_redirect_always_follow, |
|---|
| 39 | +MODULE_PARM_DESC(redirect_always_follow, |
|---|
| 42 | 40 | "Follow redirects even if redirect_dir feature is turned off"); |
|---|
| 43 | 41 | |
|---|
| 44 | 42 | static bool ovl_index_def = IS_ENABLED(CONFIG_OVERLAY_FS_INDEX); |
|---|
| 45 | 43 | module_param_named(index, ovl_index_def, bool, 0644); |
|---|
| 46 | | -MODULE_PARM_DESC(ovl_index_def, |
|---|
| 44 | +MODULE_PARM_DESC(index, |
|---|
| 47 | 45 | "Default to on or off for the inodes index feature"); |
|---|
| 48 | 46 | |
|---|
| 49 | 47 | static bool ovl_nfs_export_def = IS_ENABLED(CONFIG_OVERLAY_FS_NFS_EXPORT); |
|---|
| 50 | 48 | module_param_named(nfs_export, ovl_nfs_export_def, bool, 0644); |
|---|
| 51 | | -MODULE_PARM_DESC(ovl_nfs_export_def, |
|---|
| 49 | +MODULE_PARM_DESC(nfs_export, |
|---|
| 52 | 50 | "Default to on or off for the NFS export feature"); |
|---|
| 53 | 51 | |
|---|
| 54 | 52 | static bool ovl_xino_auto_def = IS_ENABLED(CONFIG_OVERLAY_FS_XINO_AUTO); |
|---|
| 55 | 53 | module_param_named(xino_auto, ovl_xino_auto_def, bool, 0644); |
|---|
| 56 | | -MODULE_PARM_DESC(ovl_xino_auto_def, |
|---|
| 54 | +MODULE_PARM_DESC(xino_auto, |
|---|
| 57 | 55 | "Auto enable xino feature"); |
|---|
| 58 | 56 | |
|---|
| 59 | 57 | static bool __read_mostly ovl_override_creds_def = true; |
|---|
| .. | .. |
|---|
| 71 | 69 | |
|---|
| 72 | 70 | static bool ovl_metacopy_def = IS_ENABLED(CONFIG_OVERLAY_FS_METACOPY); |
|---|
| 73 | 71 | module_param_named(metacopy, ovl_metacopy_def, bool, 0644); |
|---|
| 74 | | -MODULE_PARM_DESC(ovl_metacopy_def, |
|---|
| 72 | +MODULE_PARM_DESC(metacopy, |
|---|
| 75 | 73 | "Default to on or off for the metadata only copy up feature"); |
|---|
| 76 | 74 | |
|---|
| 77 | 75 | static void ovl_dentry_release(struct dentry *dentry) |
|---|
| .. | .. |
|---|
| 124 | 122 | return dentry; |
|---|
| 125 | 123 | } |
|---|
| 126 | 124 | |
|---|
| 127 | | -static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags) |
|---|
| 125 | +static int ovl_revalidate_real(struct dentry *d, unsigned int flags, bool weak) |
|---|
| 128 | 126 | { |
|---|
| 129 | | - struct ovl_entry *oe = dentry->d_fsdata; |
|---|
| 130 | | - unsigned int i; |
|---|
| 131 | 127 | int ret = 1; |
|---|
| 132 | 128 | |
|---|
| 133 | | - for (i = 0; i < oe->numlower; i++) { |
|---|
| 134 | | - struct dentry *d = oe->lowerstack[i].dentry; |
|---|
| 135 | | - |
|---|
| 136 | | - if (d->d_flags & DCACHE_OP_REVALIDATE) { |
|---|
| 137 | | - ret = d->d_op->d_revalidate(d, flags); |
|---|
| 138 | | - if (ret < 0) |
|---|
| 139 | | - return ret; |
|---|
| 140 | | - if (!ret) { |
|---|
| 141 | | - if (!(flags & LOOKUP_RCU)) |
|---|
| 142 | | - d_invalidate(d); |
|---|
| 143 | | - return -ESTALE; |
|---|
| 144 | | - } |
|---|
| 145 | | - } |
|---|
| 146 | | - } |
|---|
| 147 | | - return 1; |
|---|
| 148 | | -} |
|---|
| 149 | | - |
|---|
| 150 | | -static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags) |
|---|
| 151 | | -{ |
|---|
| 152 | | - struct ovl_entry *oe = dentry->d_fsdata; |
|---|
| 153 | | - unsigned int i; |
|---|
| 154 | | - int ret = 1; |
|---|
| 155 | | - |
|---|
| 156 | | - for (i = 0; i < oe->numlower; i++) { |
|---|
| 157 | | - struct dentry *d = oe->lowerstack[i].dentry; |
|---|
| 158 | | - |
|---|
| 159 | | - if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE) { |
|---|
| 160 | | - ret = d->d_op->d_weak_revalidate(d, flags); |
|---|
| 161 | | - if (ret <= 0) |
|---|
| 162 | | - break; |
|---|
| 129 | + if (weak) { |
|---|
| 130 | + if (d->d_flags & DCACHE_OP_WEAK_REVALIDATE) |
|---|
| 131 | + ret = d->d_op->d_weak_revalidate(d, flags); |
|---|
| 132 | + } else if (d->d_flags & DCACHE_OP_REVALIDATE) { |
|---|
| 133 | + ret = d->d_op->d_revalidate(d, flags); |
|---|
| 134 | + if (!ret) { |
|---|
| 135 | + if (!(flags & LOOKUP_RCU)) |
|---|
| 136 | + d_invalidate(d); |
|---|
| 137 | + ret = -ESTALE; |
|---|
| 163 | 138 | } |
|---|
| 164 | 139 | } |
|---|
| 165 | 140 | return ret; |
|---|
| 166 | 141 | } |
|---|
| 167 | 142 | |
|---|
| 168 | | -static const struct dentry_operations ovl_dentry_operations = { |
|---|
| 169 | | - .d_release = ovl_dentry_release, |
|---|
| 170 | | - .d_real = ovl_d_real, |
|---|
| 171 | | -}; |
|---|
| 143 | +static int ovl_dentry_revalidate_common(struct dentry *dentry, |
|---|
| 144 | + unsigned int flags, bool weak) |
|---|
| 145 | +{ |
|---|
| 146 | + struct ovl_entry *oe = dentry->d_fsdata; |
|---|
| 147 | + struct dentry *upper; |
|---|
| 148 | + unsigned int i; |
|---|
| 149 | + int ret = 1; |
|---|
| 172 | 150 | |
|---|
| 173 | | -static const struct dentry_operations ovl_reval_dentry_operations = { |
|---|
| 151 | + upper = ovl_dentry_upper(dentry); |
|---|
| 152 | + if (upper) |
|---|
| 153 | + ret = ovl_revalidate_real(upper, flags, weak); |
|---|
| 154 | + |
|---|
| 155 | + for (i = 0; ret > 0 && i < oe->numlower; i++) { |
|---|
| 156 | + ret = ovl_revalidate_real(oe->lowerstack[i].dentry, flags, |
|---|
| 157 | + weak); |
|---|
| 158 | + } |
|---|
| 159 | + return ret; |
|---|
| 160 | +} |
|---|
| 161 | + |
|---|
| 162 | +static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags) |
|---|
| 163 | +{ |
|---|
| 164 | + return ovl_dentry_revalidate_common(dentry, flags, false); |
|---|
| 165 | +} |
|---|
| 166 | + |
|---|
| 167 | +static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags) |
|---|
| 168 | +{ |
|---|
| 169 | + return ovl_dentry_revalidate_common(dentry, flags, true); |
|---|
| 170 | +} |
|---|
| 171 | + |
|---|
| 172 | +static const struct dentry_operations ovl_dentry_operations = { |
|---|
| 174 | 173 | .d_release = ovl_dentry_release, |
|---|
| 175 | 174 | .d_real = ovl_d_real, |
|---|
| 176 | 175 | .d_revalidate = ovl_dentry_revalidate, |
|---|
| .. | .. |
|---|
| 198 | 197 | return &oi->vfs_inode; |
|---|
| 199 | 198 | } |
|---|
| 200 | 199 | |
|---|
| 201 | | -static void ovl_i_callback(struct rcu_head *head) |
|---|
| 200 | +static void ovl_free_inode(struct inode *inode) |
|---|
| 202 | 201 | { |
|---|
| 203 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 202 | + struct ovl_inode *oi = OVL_I(inode); |
|---|
| 204 | 203 | |
|---|
| 205 | | - kmem_cache_free(ovl_inode_cachep, OVL_I(inode)); |
|---|
| 204 | + kfree(oi->redirect); |
|---|
| 205 | + mutex_destroy(&oi->lock); |
|---|
| 206 | + kmem_cache_free(ovl_inode_cachep, oi); |
|---|
| 206 | 207 | } |
|---|
| 207 | 208 | |
|---|
| 208 | 209 | static void ovl_destroy_inode(struct inode *inode) |
|---|
| .. | .. |
|---|
| 215 | 216 | ovl_dir_cache_free(inode); |
|---|
| 216 | 217 | else |
|---|
| 217 | 218 | iput(oi->lowerdata); |
|---|
| 218 | | - kfree(oi->redirect); |
|---|
| 219 | | - mutex_destroy(&oi->lock); |
|---|
| 220 | | - |
|---|
| 221 | | - call_rcu(&inode->i_rcu, ovl_i_callback); |
|---|
| 222 | 219 | } |
|---|
| 223 | 220 | |
|---|
| 224 | 221 | static void ovl_free_fs(struct ovl_fs *ofs) |
|---|
| 225 | 222 | { |
|---|
| 223 | + struct vfsmount **mounts; |
|---|
| 226 | 224 | unsigned i; |
|---|
| 227 | 225 | |
|---|
| 228 | 226 | iput(ofs->workbasedir_trap); |
|---|
| 229 | 227 | iput(ofs->indexdir_trap); |
|---|
| 230 | 228 | iput(ofs->workdir_trap); |
|---|
| 231 | | - iput(ofs->upperdir_trap); |
|---|
| 229 | + dput(ofs->whiteout); |
|---|
| 232 | 230 | dput(ofs->indexdir); |
|---|
| 233 | 231 | dput(ofs->workdir); |
|---|
| 234 | 232 | if (ofs->workdir_locked) |
|---|
| 235 | 233 | ovl_inuse_unlock(ofs->workbasedir); |
|---|
| 236 | 234 | dput(ofs->workbasedir); |
|---|
| 237 | 235 | if (ofs->upperdir_locked) |
|---|
| 238 | | - ovl_inuse_unlock(ofs->upper_mnt->mnt_root); |
|---|
| 239 | | - mntput(ofs->upper_mnt); |
|---|
| 240 | | - for (i = 0; i < ofs->numlower; i++) { |
|---|
| 241 | | - iput(ofs->lower_layers[i].trap); |
|---|
| 242 | | - mntput(ofs->lower_layers[i].mnt); |
|---|
| 236 | + ovl_inuse_unlock(ovl_upper_mnt(ofs)->mnt_root); |
|---|
| 237 | + |
|---|
| 238 | + /* Hack! Reuse ofs->layers as a vfsmount array before freeing it */ |
|---|
| 239 | + mounts = (struct vfsmount **) ofs->layers; |
|---|
| 240 | + for (i = 0; i < ofs->numlayer; i++) { |
|---|
| 241 | + iput(ofs->layers[i].trap); |
|---|
| 242 | + mounts[i] = ofs->layers[i].mnt; |
|---|
| 243 | 243 | } |
|---|
| 244 | | - for (i = 0; i < ofs->numlowerfs; i++) |
|---|
| 245 | | - free_anon_bdev(ofs->lower_fs[i].pseudo_dev); |
|---|
| 246 | | - kfree(ofs->lower_layers); |
|---|
| 247 | | - kfree(ofs->lower_fs); |
|---|
| 244 | + kern_unmount_array(mounts, ofs->numlayer); |
|---|
| 245 | + kfree(ofs->layers); |
|---|
| 246 | + for (i = 0; i < ofs->numfs; i++) |
|---|
| 247 | + free_anon_bdev(ofs->fs[i].pseudo_dev); |
|---|
| 248 | + kfree(ofs->fs); |
|---|
| 248 | 249 | |
|---|
| 249 | 250 | kfree(ofs->config.lowerdir); |
|---|
| 250 | 251 | kfree(ofs->config.upperdir); |
|---|
| .. | .. |
|---|
| 269 | 270 | struct super_block *upper_sb; |
|---|
| 270 | 271 | int ret; |
|---|
| 271 | 272 | |
|---|
| 272 | | - if (!ofs->upper_mnt) |
|---|
| 273 | | - return 0; |
|---|
| 273 | + ret = ovl_sync_status(ofs); |
|---|
| 274 | + /* |
|---|
| 275 | + * We have to always set the err, because the return value isn't |
|---|
| 276 | + * checked in syncfs, and instead indirectly return an error via |
|---|
| 277 | + * the sb's writeback errseq, which VFS inspects after this call. |
|---|
| 278 | + */ |
|---|
| 279 | + if (ret < 0) { |
|---|
| 280 | + errseq_set(&sb->s_wb_err, -EIO); |
|---|
| 281 | + return -EIO; |
|---|
| 282 | + } |
|---|
| 283 | + |
|---|
| 284 | + if (!ret) |
|---|
| 285 | + return ret; |
|---|
| 274 | 286 | |
|---|
| 275 | 287 | /* |
|---|
| 276 | | - * If this is a sync(2) call or an emergency sync, all the super blocks |
|---|
| 277 | | - * will be iterated, including upper_sb, so no need to do anything. |
|---|
| 288 | + * Not called for sync(2) call or an emergency sync (SB_I_SKIP_SYNC). |
|---|
| 289 | + * All the super blocks will be iterated, including upper_sb. |
|---|
| 278 | 290 | * |
|---|
| 279 | 291 | * If this is a syncfs(2) call, then we do need to call |
|---|
| 280 | 292 | * sync_filesystem() on upper_sb, but enough if we do it when being |
|---|
| .. | .. |
|---|
| 283 | 295 | if (!wait) |
|---|
| 284 | 296 | return 0; |
|---|
| 285 | 297 | |
|---|
| 286 | | - upper_sb = ofs->upper_mnt->mnt_sb; |
|---|
| 298 | + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; |
|---|
| 287 | 299 | |
|---|
| 288 | 300 | down_read(&upper_sb->s_umount); |
|---|
| 289 | 301 | ret = sync_filesystem(upper_sb); |
|---|
| .. | .. |
|---|
| 321 | 333 | /* Will this overlay be forced to mount/remount ro? */ |
|---|
| 322 | 334 | static bool ovl_force_readonly(struct ovl_fs *ofs) |
|---|
| 323 | 335 | { |
|---|
| 324 | | - return (!ofs->upper_mnt || !ofs->workdir); |
|---|
| 336 | + return (!ovl_upper_mnt(ofs) || !ofs->workdir); |
|---|
| 325 | 337 | } |
|---|
| 326 | 338 | |
|---|
| 327 | 339 | static const char *ovl_redirect_mode_def(void) |
|---|
| 328 | 340 | { |
|---|
| 329 | 341 | return ovl_redirect_dir_def ? "on" : "off"; |
|---|
| 330 | 342 | } |
|---|
| 331 | | - |
|---|
| 332 | | -enum { |
|---|
| 333 | | - OVL_XINO_OFF, |
|---|
| 334 | | - OVL_XINO_AUTO, |
|---|
| 335 | | - OVL_XINO_ON, |
|---|
| 336 | | -}; |
|---|
| 337 | 343 | |
|---|
| 338 | 344 | static const char * const ovl_xino_str[] = { |
|---|
| 339 | 345 | "off", |
|---|
| .. | .. |
|---|
| 371 | 377 | if (ofs->config.nfs_export != ovl_nfs_export_def) |
|---|
| 372 | 378 | seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ? |
|---|
| 373 | 379 | "on" : "off"); |
|---|
| 374 | | - if (ofs->config.xino != ovl_xino_def()) |
|---|
| 380 | + if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(sb)) |
|---|
| 375 | 381 | seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]); |
|---|
| 376 | 382 | if (ofs->config.metacopy != ovl_metacopy_def) |
|---|
| 377 | 383 | seq_printf(m, ",metacopy=%s", |
|---|
| 378 | 384 | ofs->config.metacopy ? "on" : "off"); |
|---|
| 385 | + if (ofs->config.ovl_volatile) |
|---|
| 386 | + seq_puts(m, ",volatile"); |
|---|
| 379 | 387 | if (ofs->config.override_creds != ovl_override_creds_def) |
|---|
| 380 | 388 | seq_show_option(m, "override_creds", |
|---|
| 381 | 389 | ofs->config.override_creds ? "on" : "off"); |
|---|
| .. | .. |
|---|
| 385 | 393 | static int ovl_remount(struct super_block *sb, int *flags, char *data) |
|---|
| 386 | 394 | { |
|---|
| 387 | 395 | struct ovl_fs *ofs = sb->s_fs_info; |
|---|
| 396 | + struct super_block *upper_sb; |
|---|
| 397 | + int ret = 0; |
|---|
| 388 | 398 | |
|---|
| 389 | 399 | if (!(*flags & SB_RDONLY) && ovl_force_readonly(ofs)) |
|---|
| 390 | 400 | return -EROFS; |
|---|
| 391 | 401 | |
|---|
| 392 | | - return 0; |
|---|
| 402 | + if (*flags & SB_RDONLY && !sb_rdonly(sb)) { |
|---|
| 403 | + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; |
|---|
| 404 | + if (ovl_should_sync(ofs)) { |
|---|
| 405 | + down_read(&upper_sb->s_umount); |
|---|
| 406 | + ret = sync_filesystem(upper_sb); |
|---|
| 407 | + up_read(&upper_sb->s_umount); |
|---|
| 408 | + } |
|---|
| 409 | + } |
|---|
| 410 | + |
|---|
| 411 | + return ret; |
|---|
| 393 | 412 | } |
|---|
| 394 | 413 | |
|---|
| 395 | 414 | static const struct super_operations ovl_super_operations = { |
|---|
| 396 | 415 | .alloc_inode = ovl_alloc_inode, |
|---|
| 416 | + .free_inode = ovl_free_inode, |
|---|
| 397 | 417 | .destroy_inode = ovl_destroy_inode, |
|---|
| 398 | 418 | .drop_inode = generic_delete_inode, |
|---|
| 399 | 419 | .put_super = ovl_put_super, |
|---|
| .. | .. |
|---|
| 418 | 438 | OPT_XINO_AUTO, |
|---|
| 419 | 439 | OPT_METACOPY_ON, |
|---|
| 420 | 440 | OPT_METACOPY_OFF, |
|---|
| 441 | + OPT_VOLATILE, |
|---|
| 421 | 442 | OPT_OVERRIDE_CREDS_ON, |
|---|
| 422 | 443 | OPT_OVERRIDE_CREDS_OFF, |
|---|
| 423 | 444 | OPT_ERR, |
|---|
| .. | .. |
|---|
| 438 | 459 | {OPT_XINO_AUTO, "xino=auto"}, |
|---|
| 439 | 460 | {OPT_METACOPY_ON, "metacopy=on"}, |
|---|
| 440 | 461 | {OPT_METACOPY_OFF, "metacopy=off"}, |
|---|
| 462 | + {OPT_VOLATILE, "volatile"}, |
|---|
| 441 | 463 | {OPT_OVERRIDE_CREDS_ON, "override_creds=on"}, |
|---|
| 442 | 464 | {OPT_OVERRIDE_CREDS_OFF, "override_creds=off"}, |
|---|
| 443 | 465 | {OPT_ERR, NULL} |
|---|
| .. | .. |
|---|
| 481 | 503 | if (ovl_redirect_always_follow) |
|---|
| 482 | 504 | config->redirect_follow = true; |
|---|
| 483 | 505 | } else if (strcmp(mode, "nofollow") != 0) { |
|---|
| 484 | | - pr_err("overlayfs: bad mount option \"redirect_dir=%s\"\n", |
|---|
| 506 | + pr_err("bad mount option \"redirect_dir=%s\"\n", |
|---|
| 485 | 507 | mode); |
|---|
| 486 | 508 | return -EINVAL; |
|---|
| 487 | 509 | } |
|---|
| .. | .. |
|---|
| 494 | 516 | char *p; |
|---|
| 495 | 517 | int err; |
|---|
| 496 | 518 | bool metacopy_opt = false, redirect_opt = false; |
|---|
| 519 | + bool nfs_export_opt = false, index_opt = false; |
|---|
| 497 | 520 | |
|---|
| 498 | 521 | config->redirect_mode = kstrdup(ovl_redirect_mode_def(), GFP_KERNEL); |
|---|
| 499 | 522 | if (!config->redirect_mode) |
|---|
| .. | .. |
|---|
| 544 | 567 | |
|---|
| 545 | 568 | case OPT_INDEX_ON: |
|---|
| 546 | 569 | config->index = true; |
|---|
| 570 | + index_opt = true; |
|---|
| 547 | 571 | break; |
|---|
| 548 | 572 | |
|---|
| 549 | 573 | case OPT_INDEX_OFF: |
|---|
| 550 | 574 | config->index = false; |
|---|
| 575 | + index_opt = true; |
|---|
| 551 | 576 | break; |
|---|
| 552 | 577 | |
|---|
| 553 | 578 | case OPT_NFS_EXPORT_ON: |
|---|
| 554 | 579 | config->nfs_export = true; |
|---|
| 580 | + nfs_export_opt = true; |
|---|
| 555 | 581 | break; |
|---|
| 556 | 582 | |
|---|
| 557 | 583 | case OPT_NFS_EXPORT_OFF: |
|---|
| 558 | 584 | config->nfs_export = false; |
|---|
| 585 | + nfs_export_opt = true; |
|---|
| 559 | 586 | break; |
|---|
| 560 | 587 | |
|---|
| 561 | 588 | case OPT_XINO_ON: |
|---|
| .. | .. |
|---|
| 577 | 604 | |
|---|
| 578 | 605 | case OPT_METACOPY_OFF: |
|---|
| 579 | 606 | config->metacopy = false; |
|---|
| 607 | + metacopy_opt = true; |
|---|
| 608 | + break; |
|---|
| 609 | + |
|---|
| 610 | + case OPT_VOLATILE: |
|---|
| 611 | + config->ovl_volatile = true; |
|---|
| 580 | 612 | break; |
|---|
| 581 | 613 | |
|---|
| 582 | 614 | case OPT_OVERRIDE_CREDS_ON: |
|---|
| .. | .. |
|---|
| 588 | 620 | break; |
|---|
| 589 | 621 | |
|---|
| 590 | 622 | default: |
|---|
| 591 | | - pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p); |
|---|
| 623 | + pr_err("unrecognized mount option \"%s\" or missing value\n", |
|---|
| 624 | + p); |
|---|
| 592 | 625 | return -EINVAL; |
|---|
| 593 | 626 | } |
|---|
| 594 | 627 | } |
|---|
| 595 | 628 | |
|---|
| 596 | | - /* Workdir is useless in non-upper mount */ |
|---|
| 597 | | - if (!config->upperdir && config->workdir) { |
|---|
| 598 | | - pr_info("overlayfs: option \"workdir=%s\" is useless in a non-upper mount, ignore\n", |
|---|
| 599 | | - config->workdir); |
|---|
| 600 | | - kfree(config->workdir); |
|---|
| 601 | | - config->workdir = NULL; |
|---|
| 629 | + /* Workdir/index are useless in non-upper mount */ |
|---|
| 630 | + if (!config->upperdir) { |
|---|
| 631 | + if (config->workdir) { |
|---|
| 632 | + pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n", |
|---|
| 633 | + config->workdir); |
|---|
| 634 | + kfree(config->workdir); |
|---|
| 635 | + config->workdir = NULL; |
|---|
| 636 | + } |
|---|
| 637 | + if (config->index && index_opt) { |
|---|
| 638 | + pr_info("option \"index=on\" is useless in a non-upper mount, ignore\n"); |
|---|
| 639 | + index_opt = false; |
|---|
| 640 | + } |
|---|
| 641 | + config->index = false; |
|---|
| 642 | + } |
|---|
| 643 | + |
|---|
| 644 | + if (!config->upperdir && config->ovl_volatile) { |
|---|
| 645 | + pr_info("option \"volatile\" is meaningless in a non-upper mount, ignoring it.\n"); |
|---|
| 646 | + config->ovl_volatile = false; |
|---|
| 602 | 647 | } |
|---|
| 603 | 648 | |
|---|
| 604 | 649 | err = ovl_parse_redirect_mode(config, config->redirect_mode); |
|---|
| .. | .. |
|---|
| 615 | 660 | /* Resolve metacopy -> redirect_dir dependency */ |
|---|
| 616 | 661 | if (config->metacopy && !config->redirect_dir) { |
|---|
| 617 | 662 | if (metacopy_opt && redirect_opt) { |
|---|
| 618 | | - pr_err("overlayfs: conflicting options: metacopy=on,redirect_dir=%s\n", |
|---|
| 663 | + pr_err("conflicting options: metacopy=on,redirect_dir=%s\n", |
|---|
| 619 | 664 | config->redirect_mode); |
|---|
| 620 | 665 | return -EINVAL; |
|---|
| 621 | 666 | } |
|---|
| .. | .. |
|---|
| 624 | 669 | * There was an explicit redirect_dir=... that resulted |
|---|
| 625 | 670 | * in this conflict. |
|---|
| 626 | 671 | */ |
|---|
| 627 | | - pr_info("overlayfs: disabling metacopy due to redirect_dir=%s\n", |
|---|
| 672 | + pr_info("disabling metacopy due to redirect_dir=%s\n", |
|---|
| 628 | 673 | config->redirect_mode); |
|---|
| 629 | 674 | config->metacopy = false; |
|---|
| 630 | 675 | } else { |
|---|
| 631 | 676 | /* Automatically enable redirect otherwise. */ |
|---|
| 632 | 677 | config->redirect_follow = config->redirect_dir = true; |
|---|
| 678 | + } |
|---|
| 679 | + } |
|---|
| 680 | + |
|---|
| 681 | + /* Resolve nfs_export -> index dependency */ |
|---|
| 682 | + if (config->nfs_export && !config->index) { |
|---|
| 683 | + if (!config->upperdir && config->redirect_follow) { |
|---|
| 684 | + pr_info("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n"); |
|---|
| 685 | + config->nfs_export = false; |
|---|
| 686 | + } else if (nfs_export_opt && index_opt) { |
|---|
| 687 | + pr_err("conflicting options: nfs_export=on,index=off\n"); |
|---|
| 688 | + return -EINVAL; |
|---|
| 689 | + } else if (index_opt) { |
|---|
| 690 | + /* |
|---|
| 691 | + * There was an explicit index=off that resulted |
|---|
| 692 | + * in this conflict. |
|---|
| 693 | + */ |
|---|
| 694 | + pr_info("disabling nfs_export due to index=off\n"); |
|---|
| 695 | + config->nfs_export = false; |
|---|
| 696 | + } else { |
|---|
| 697 | + /* Automatically enable index otherwise. */ |
|---|
| 698 | + config->index = true; |
|---|
| 699 | + } |
|---|
| 700 | + } |
|---|
| 701 | + |
|---|
| 702 | + /* Resolve nfs_export -> !metacopy dependency */ |
|---|
| 703 | + if (config->nfs_export && config->metacopy) { |
|---|
| 704 | + if (nfs_export_opt && metacopy_opt) { |
|---|
| 705 | + pr_err("conflicting options: nfs_export=on,metacopy=on\n"); |
|---|
| 706 | + return -EINVAL; |
|---|
| 707 | + } |
|---|
| 708 | + if (metacopy_opt) { |
|---|
| 709 | + /* |
|---|
| 710 | + * There was an explicit metacopy=on that resulted |
|---|
| 711 | + * in this conflict. |
|---|
| 712 | + */ |
|---|
| 713 | + pr_info("disabling nfs_export due to metacopy=on\n"); |
|---|
| 714 | + config->nfs_export = false; |
|---|
| 715 | + } else { |
|---|
| 716 | + /* |
|---|
| 717 | + * There was an explicit nfs_export=on that resulted |
|---|
| 718 | + * in this conflict. |
|---|
| 719 | + */ |
|---|
| 720 | + pr_info("disabling metacopy due to nfs_export=on\n"); |
|---|
| 721 | + config->metacopy = false; |
|---|
| 633 | 722 | } |
|---|
| 634 | 723 | } |
|---|
| 635 | 724 | |
|---|
| .. | .. |
|---|
| 643 | 732 | const char *name, bool persist) |
|---|
| 644 | 733 | { |
|---|
| 645 | 734 | struct inode *dir = ofs->workbasedir->d_inode; |
|---|
| 646 | | - struct vfsmount *mnt = ofs->upper_mnt; |
|---|
| 735 | + struct vfsmount *mnt = ovl_upper_mnt(ofs); |
|---|
| 647 | 736 | struct dentry *work; |
|---|
| 648 | 737 | int err; |
|---|
| 649 | 738 | bool retried = false; |
|---|
| 650 | | - bool locked = false; |
|---|
| 651 | 739 | |
|---|
| 652 | 740 | inode_lock_nested(dir, I_MUTEX_PARENT); |
|---|
| 653 | | - locked = true; |
|---|
| 654 | | - |
|---|
| 655 | 741 | retry: |
|---|
| 656 | 742 | work = lookup_one_len(name, ofs->workbasedir, strlen(name)); |
|---|
| 657 | 743 | |
|---|
| .. | .. |
|---|
| 670 | 756 | goto out_unlock; |
|---|
| 671 | 757 | |
|---|
| 672 | 758 | retried = true; |
|---|
| 673 | | - ovl_workdir_cleanup(dir, mnt, work, 0); |
|---|
| 759 | + err = ovl_workdir_cleanup(dir, mnt, work, 0); |
|---|
| 674 | 760 | dput(work); |
|---|
| 761 | + if (err == -EINVAL) { |
|---|
| 762 | + work = ERR_PTR(err); |
|---|
| 763 | + goto out_unlock; |
|---|
| 764 | + } |
|---|
| 675 | 765 | goto retry; |
|---|
| 676 | 766 | } |
|---|
| 677 | 767 | |
|---|
| .. | .. |
|---|
| 716 | 806 | goto out_err; |
|---|
| 717 | 807 | } |
|---|
| 718 | 808 | out_unlock: |
|---|
| 719 | | - if (locked) |
|---|
| 720 | | - inode_unlock(dir); |
|---|
| 721 | | - |
|---|
| 809 | + inode_unlock(dir); |
|---|
| 722 | 810 | return work; |
|---|
| 723 | 811 | |
|---|
| 724 | 812 | out_dput: |
|---|
| 725 | 813 | dput(work); |
|---|
| 726 | 814 | out_err: |
|---|
| 727 | | - pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n", |
|---|
| 815 | + pr_warn("failed to create directory %s/%s (errno: %i); mounting read-only\n", |
|---|
| 728 | 816 | ofs->config.workdir, name, -err); |
|---|
| 729 | 817 | work = NULL; |
|---|
| 730 | 818 | goto out_unlock; |
|---|
| .. | .. |
|---|
| 748 | 836 | int err = -EINVAL; |
|---|
| 749 | 837 | |
|---|
| 750 | 838 | if (!*name) { |
|---|
| 751 | | - pr_err("overlayfs: empty lowerdir\n"); |
|---|
| 839 | + pr_err("empty lowerdir\n"); |
|---|
| 752 | 840 | goto out; |
|---|
| 753 | 841 | } |
|---|
| 754 | 842 | err = kern_path(name, LOOKUP_FOLLOW, path); |
|---|
| 755 | 843 | if (err) { |
|---|
| 756 | | - pr_err("overlayfs: failed to resolve '%s': %i\n", name, err); |
|---|
| 844 | + pr_err("failed to resolve '%s': %i\n", name, err); |
|---|
| 757 | 845 | goto out; |
|---|
| 758 | 846 | } |
|---|
| 759 | 847 | err = -EINVAL; |
|---|
| 760 | 848 | if (ovl_dentry_weird(path->dentry)) { |
|---|
| 761 | | - pr_err("overlayfs: filesystem on '%s' not supported\n", name); |
|---|
| 849 | + pr_err("filesystem on '%s' not supported\n", name); |
|---|
| 762 | 850 | goto out_put; |
|---|
| 763 | 851 | } |
|---|
| 764 | 852 | if (!d_is_dir(path->dentry)) { |
|---|
| 765 | | - pr_err("overlayfs: '%s' not a directory\n", name); |
|---|
| 853 | + pr_err("'%s' not a directory\n", name); |
|---|
| 766 | 854 | goto out_put; |
|---|
| 767 | 855 | } |
|---|
| 768 | 856 | return 0; |
|---|
| .. | .. |
|---|
| 782 | 870 | ovl_unescape(tmp); |
|---|
| 783 | 871 | err = ovl_mount_dir_noesc(tmp, path); |
|---|
| 784 | 872 | |
|---|
| 785 | | - if (!err) |
|---|
| 786 | | - if (ovl_dentry_remote(path->dentry)) { |
|---|
| 787 | | - pr_err("overlayfs: filesystem on '%s' not supported as upperdir\n", |
|---|
| 788 | | - tmp); |
|---|
| 789 | | - path_put_init(path); |
|---|
| 790 | | - err = -EINVAL; |
|---|
| 791 | | - } |
|---|
| 873 | + if (!err && path->dentry->d_flags & DCACHE_OP_REAL) { |
|---|
| 874 | + pr_err("filesystem on '%s' not supported as upperdir\n", |
|---|
| 875 | + tmp); |
|---|
| 876 | + path_put_init(path); |
|---|
| 877 | + err = -EINVAL; |
|---|
| 878 | + } |
|---|
| 792 | 879 | kfree(tmp); |
|---|
| 793 | 880 | } |
|---|
| 794 | 881 | return err; |
|---|
| .. | .. |
|---|
| 801 | 888 | int err = vfs_statfs(path, &statfs); |
|---|
| 802 | 889 | |
|---|
| 803 | 890 | if (err) |
|---|
| 804 | | - pr_err("overlayfs: statfs failed on '%s'\n", name); |
|---|
| 891 | + pr_err("statfs failed on '%s'\n", name); |
|---|
| 805 | 892 | else |
|---|
| 806 | 893 | ofs->namelen = max(ofs->namelen, statfs.f_namelen); |
|---|
| 807 | 894 | |
|---|
| .. | .. |
|---|
| 809 | 896 | } |
|---|
| 810 | 897 | |
|---|
| 811 | 898 | static int ovl_lower_dir(const char *name, struct path *path, |
|---|
| 812 | | - struct ovl_fs *ofs, int *stack_depth, bool *remote) |
|---|
| 899 | + struct ovl_fs *ofs, int *stack_depth) |
|---|
| 813 | 900 | { |
|---|
| 814 | 901 | int fh_type; |
|---|
| 815 | 902 | int err; |
|---|
| 816 | 903 | |
|---|
| 817 | 904 | err = ovl_mount_dir_noesc(name, path); |
|---|
| 818 | 905 | if (err) |
|---|
| 819 | | - goto out; |
|---|
| 906 | + return err; |
|---|
| 820 | 907 | |
|---|
| 821 | 908 | err = ovl_check_namelen(path, ofs, name); |
|---|
| 822 | 909 | if (err) |
|---|
| 823 | | - goto out_put; |
|---|
| 910 | + return err; |
|---|
| 824 | 911 | |
|---|
| 825 | 912 | *stack_depth = max(*stack_depth, path->mnt->mnt_sb->s_stack_depth); |
|---|
| 826 | | - |
|---|
| 827 | | - if (ovl_dentry_remote(path->dentry)) |
|---|
| 828 | | - *remote = true; |
|---|
| 829 | 913 | |
|---|
| 830 | 914 | /* |
|---|
| 831 | 915 | * The inodes index feature and NFS export need to encode and decode |
|---|
| .. | .. |
|---|
| 836 | 920 | (ofs->config.index && ofs->config.upperdir)) && !fh_type) { |
|---|
| 837 | 921 | ofs->config.index = false; |
|---|
| 838 | 922 | ofs->config.nfs_export = false; |
|---|
| 839 | | - pr_warn("overlayfs: fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n", |
|---|
| 923 | + pr_warn("fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n", |
|---|
| 840 | 924 | name); |
|---|
| 841 | 925 | } |
|---|
| 842 | 926 | |
|---|
| 843 | 927 | /* Check if lower fs has 32bit inode numbers */ |
|---|
| 844 | 928 | if (fh_type != FILEID_INO32_GEN) |
|---|
| 845 | | - ofs->xino_bits = 0; |
|---|
| 929 | + ofs->xino_mode = -1; |
|---|
| 846 | 930 | |
|---|
| 847 | 931 | return 0; |
|---|
| 848 | | - |
|---|
| 849 | | -out_put: |
|---|
| 850 | | - path_put_init(path); |
|---|
| 851 | | -out: |
|---|
| 852 | | - return err; |
|---|
| 853 | 932 | } |
|---|
| 854 | 933 | |
|---|
| 855 | 934 | /* Workdir should not be subdir of upperdir and vice versa */ |
|---|
| .. | .. |
|---|
| 887 | 966 | static int __maybe_unused |
|---|
| 888 | 967 | ovl_posix_acl_xattr_get(const struct xattr_handler *handler, |
|---|
| 889 | 968 | struct dentry *dentry, struct inode *inode, |
|---|
| 890 | | - const char *name, void *buffer, size_t size) |
|---|
| 969 | + const char *name, void *buffer, size_t size, int flags) |
|---|
| 891 | 970 | { |
|---|
| 892 | | - return ovl_xattr_get(dentry, inode, handler->name, buffer, size); |
|---|
| 893 | | -} |
|---|
| 894 | | - |
|---|
| 895 | | -static int __maybe_unused |
|---|
| 896 | | -__ovl_posix_acl_xattr_get(const struct xattr_handler *handler, |
|---|
| 897 | | - struct dentry *dentry, struct inode *inode, |
|---|
| 898 | | - const char *name, void *buffer, size_t size) |
|---|
| 899 | | -{ |
|---|
| 900 | | - return __ovl_xattr_get(dentry, inode, handler->name, buffer, size); |
|---|
| 971 | + return ovl_xattr_get(dentry, inode, handler->name, buffer, size, flags); |
|---|
| 901 | 972 | } |
|---|
| 902 | 973 | |
|---|
| 903 | 974 | static int __maybe_unused |
|---|
| .. | .. |
|---|
| 960 | 1031 | |
|---|
| 961 | 1032 | static int ovl_own_xattr_get(const struct xattr_handler *handler, |
|---|
| 962 | 1033 | struct dentry *dentry, struct inode *inode, |
|---|
| 963 | | - const char *name, void *buffer, size_t size) |
|---|
| 1034 | + const char *name, void *buffer, size_t size, |
|---|
| 1035 | + int flags) |
|---|
| 964 | 1036 | { |
|---|
| 965 | 1037 | return -EOPNOTSUPP; |
|---|
| 966 | 1038 | } |
|---|
| .. | .. |
|---|
| 975 | 1047 | |
|---|
| 976 | 1048 | static int ovl_other_xattr_get(const struct xattr_handler *handler, |
|---|
| 977 | 1049 | struct dentry *dentry, struct inode *inode, |
|---|
| 978 | | - const char *name, void *buffer, size_t size) |
|---|
| 1050 | + const char *name, void *buffer, size_t size, |
|---|
| 1051 | + int flags) |
|---|
| 979 | 1052 | { |
|---|
| 980 | | - return ovl_xattr_get(dentry, inode, name, buffer, size); |
|---|
| 981 | | -} |
|---|
| 982 | | - |
|---|
| 983 | | -static int __ovl_other_xattr_get(const struct xattr_handler *handler, |
|---|
| 984 | | - struct dentry *dentry, struct inode *inode, |
|---|
| 985 | | - const char *name, void *buffer, size_t size) |
|---|
| 986 | | -{ |
|---|
| 987 | | - return __ovl_xattr_get(dentry, inode, name, buffer, size); |
|---|
| 1053 | + return ovl_xattr_get(dentry, inode, name, buffer, size, flags); |
|---|
| 988 | 1054 | } |
|---|
| 989 | 1055 | |
|---|
| 990 | 1056 | static int ovl_other_xattr_set(const struct xattr_handler *handler, |
|---|
| .. | .. |
|---|
| 1000 | 1066 | .name = XATTR_NAME_POSIX_ACL_ACCESS, |
|---|
| 1001 | 1067 | .flags = ACL_TYPE_ACCESS, |
|---|
| 1002 | 1068 | .get = ovl_posix_acl_xattr_get, |
|---|
| 1003 | | - .__get = __ovl_posix_acl_xattr_get, |
|---|
| 1004 | 1069 | .set = ovl_posix_acl_xattr_set, |
|---|
| 1005 | 1070 | }; |
|---|
| 1006 | 1071 | |
|---|
| .. | .. |
|---|
| 1009 | 1074 | .name = XATTR_NAME_POSIX_ACL_DEFAULT, |
|---|
| 1010 | 1075 | .flags = ACL_TYPE_DEFAULT, |
|---|
| 1011 | 1076 | .get = ovl_posix_acl_xattr_get, |
|---|
| 1012 | | - .__get = __ovl_posix_acl_xattr_get, |
|---|
| 1013 | 1077 | .set = ovl_posix_acl_xattr_set, |
|---|
| 1014 | 1078 | }; |
|---|
| 1015 | 1079 | |
|---|
| .. | .. |
|---|
| 1022 | 1086 | static const struct xattr_handler ovl_other_xattr_handler = { |
|---|
| 1023 | 1087 | .prefix = "", /* catch all */ |
|---|
| 1024 | 1088 | .get = ovl_other_xattr_get, |
|---|
| 1025 | | - .__get = __ovl_other_xattr_get, |
|---|
| 1026 | 1089 | .set = ovl_other_xattr_set, |
|---|
| 1027 | 1090 | }; |
|---|
| 1028 | 1091 | |
|---|
| .. | .. |
|---|
| 1046 | 1109 | err = PTR_ERR_OR_ZERO(trap); |
|---|
| 1047 | 1110 | if (err) { |
|---|
| 1048 | 1111 | if (err == -ELOOP) |
|---|
| 1049 | | - pr_err("overlayfs: conflicting %s path\n", name); |
|---|
| 1112 | + pr_err("conflicting %s path\n", name); |
|---|
| 1050 | 1113 | return err; |
|---|
| 1051 | 1114 | } |
|---|
| 1052 | 1115 | |
|---|
| .. | .. |
|---|
| 1063 | 1126 | static int ovl_report_in_use(struct ovl_fs *ofs, const char *name) |
|---|
| 1064 | 1127 | { |
|---|
| 1065 | 1128 | if (ofs->config.index) { |
|---|
| 1066 | | - pr_err("overlayfs: %s is in-use as upperdir/workdir of another mount, mount with '-o index=off' to override exclusive upperdir protection.\n", |
|---|
| 1129 | + pr_err("%s is in-use as upperdir/workdir of another mount, mount with '-o index=off' to override exclusive upperdir protection.\n", |
|---|
| 1067 | 1130 | name); |
|---|
| 1068 | 1131 | return -EBUSY; |
|---|
| 1069 | 1132 | } else { |
|---|
| 1070 | | - pr_warn("overlayfs: %s is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.\n", |
|---|
| 1133 | + pr_warn("%s is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.\n", |
|---|
| 1071 | 1134 | name); |
|---|
| 1072 | 1135 | return 0; |
|---|
| 1073 | 1136 | } |
|---|
| 1074 | 1137 | } |
|---|
| 1075 | 1138 | |
|---|
| 1076 | 1139 | static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs, |
|---|
| 1077 | | - struct path *upperpath) |
|---|
| 1140 | + struct ovl_layer *upper_layer, struct path *upperpath) |
|---|
| 1078 | 1141 | { |
|---|
| 1079 | 1142 | struct vfsmount *upper_mnt; |
|---|
| 1080 | 1143 | int err; |
|---|
| .. | .. |
|---|
| 1085 | 1148 | |
|---|
| 1086 | 1149 | /* Upper fs should not be r/o */ |
|---|
| 1087 | 1150 | if (sb_rdonly(upperpath->mnt->mnt_sb)) { |
|---|
| 1088 | | - pr_err("overlayfs: upper fs is r/o, try multi-lower layers mount\n"); |
|---|
| 1151 | + pr_err("upper fs is r/o, try multi-lower layers mount\n"); |
|---|
| 1089 | 1152 | err = -EINVAL; |
|---|
| 1090 | 1153 | goto out; |
|---|
| 1091 | 1154 | } |
|---|
| .. | .. |
|---|
| 1094 | 1157 | if (err) |
|---|
| 1095 | 1158 | goto out; |
|---|
| 1096 | 1159 | |
|---|
| 1097 | | - err = ovl_setup_trap(sb, upperpath->dentry, &ofs->upperdir_trap, |
|---|
| 1160 | + err = ovl_setup_trap(sb, upperpath->dentry, &upper_layer->trap, |
|---|
| 1098 | 1161 | "upperdir"); |
|---|
| 1099 | 1162 | if (err) |
|---|
| 1100 | 1163 | goto out; |
|---|
| .. | .. |
|---|
| 1102 | 1165 | upper_mnt = clone_private_mount(upperpath); |
|---|
| 1103 | 1166 | err = PTR_ERR(upper_mnt); |
|---|
| 1104 | 1167 | if (IS_ERR(upper_mnt)) { |
|---|
| 1105 | | - pr_err("overlayfs: failed to clone upperpath\n"); |
|---|
| 1168 | + pr_err("failed to clone upperpath\n"); |
|---|
| 1106 | 1169 | goto out; |
|---|
| 1107 | 1170 | } |
|---|
| 1108 | 1171 | |
|---|
| 1109 | 1172 | /* Don't inherit atime flags */ |
|---|
| 1110 | 1173 | upper_mnt->mnt_flags &= ~(MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME); |
|---|
| 1111 | | - ofs->upper_mnt = upper_mnt; |
|---|
| 1174 | + upper_layer->mnt = upper_mnt; |
|---|
| 1175 | + upper_layer->idx = 0; |
|---|
| 1176 | + upper_layer->fsid = 0; |
|---|
| 1112 | 1177 | |
|---|
| 1113 | | - if (ovl_inuse_trylock(ofs->upper_mnt->mnt_root)) { |
|---|
| 1178 | + /* |
|---|
| 1179 | + * Inherit SB_NOSEC flag from upperdir. |
|---|
| 1180 | + * |
|---|
| 1181 | + * This optimization changes behavior when a security related attribute |
|---|
| 1182 | + * (suid/sgid/security.*) is changed on an underlying layer. This is |
|---|
| 1183 | + * okay because we don't yet have guarantees in that case, but it will |
|---|
| 1184 | + * need careful treatment once we want to honour changes to underlying |
|---|
| 1185 | + * filesystems. |
|---|
| 1186 | + */ |
|---|
| 1187 | + if (upper_mnt->mnt_sb->s_flags & SB_NOSEC) |
|---|
| 1188 | + sb->s_flags |= SB_NOSEC; |
|---|
| 1189 | + |
|---|
| 1190 | + if (ovl_inuse_trylock(ovl_upper_mnt(ofs)->mnt_root)) { |
|---|
| 1114 | 1191 | ofs->upperdir_locked = true; |
|---|
| 1115 | 1192 | } else { |
|---|
| 1116 | 1193 | err = ovl_report_in_use(ofs, "upperdir"); |
|---|
| .. | .. |
|---|
| 1123 | 1200 | return err; |
|---|
| 1124 | 1201 | } |
|---|
| 1125 | 1202 | |
|---|
| 1203 | +/* |
|---|
| 1204 | + * Returns 1 if RENAME_WHITEOUT is supported, 0 if not supported and |
|---|
| 1205 | + * negative values if error is encountered. |
|---|
| 1206 | + */ |
|---|
| 1207 | +static int ovl_check_rename_whiteout(struct dentry *workdir) |
|---|
| 1208 | +{ |
|---|
| 1209 | + struct inode *dir = d_inode(workdir); |
|---|
| 1210 | + struct dentry *temp; |
|---|
| 1211 | + struct dentry *dest; |
|---|
| 1212 | + struct dentry *whiteout; |
|---|
| 1213 | + struct name_snapshot name; |
|---|
| 1214 | + int err; |
|---|
| 1215 | + |
|---|
| 1216 | + inode_lock_nested(dir, I_MUTEX_PARENT); |
|---|
| 1217 | + |
|---|
| 1218 | + temp = ovl_create_temp(workdir, OVL_CATTR(S_IFREG | 0)); |
|---|
| 1219 | + err = PTR_ERR(temp); |
|---|
| 1220 | + if (IS_ERR(temp)) |
|---|
| 1221 | + goto out_unlock; |
|---|
| 1222 | + |
|---|
| 1223 | + dest = ovl_lookup_temp(workdir); |
|---|
| 1224 | + err = PTR_ERR(dest); |
|---|
| 1225 | + if (IS_ERR(dest)) { |
|---|
| 1226 | + dput(temp); |
|---|
| 1227 | + goto out_unlock; |
|---|
| 1228 | + } |
|---|
| 1229 | + |
|---|
| 1230 | + /* Name is inline and stable - using snapshot as a copy helper */ |
|---|
| 1231 | + take_dentry_name_snapshot(&name, temp); |
|---|
| 1232 | + err = ovl_do_rename(dir, temp, dir, dest, RENAME_WHITEOUT); |
|---|
| 1233 | + if (err) { |
|---|
| 1234 | + if (err == -EINVAL) |
|---|
| 1235 | + err = 0; |
|---|
| 1236 | + goto cleanup_temp; |
|---|
| 1237 | + } |
|---|
| 1238 | + |
|---|
| 1239 | + whiteout = lookup_one_len(name.name.name, workdir, name.name.len); |
|---|
| 1240 | + err = PTR_ERR(whiteout); |
|---|
| 1241 | + if (IS_ERR(whiteout)) |
|---|
| 1242 | + goto cleanup_temp; |
|---|
| 1243 | + |
|---|
| 1244 | + err = ovl_is_whiteout(whiteout); |
|---|
| 1245 | + |
|---|
| 1246 | + /* Best effort cleanup of whiteout and temp file */ |
|---|
| 1247 | + if (err) |
|---|
| 1248 | + ovl_cleanup(dir, whiteout); |
|---|
| 1249 | + dput(whiteout); |
|---|
| 1250 | + |
|---|
| 1251 | +cleanup_temp: |
|---|
| 1252 | + ovl_cleanup(dir, temp); |
|---|
| 1253 | + release_dentry_name_snapshot(&name); |
|---|
| 1254 | + dput(temp); |
|---|
| 1255 | + dput(dest); |
|---|
| 1256 | + |
|---|
| 1257 | +out_unlock: |
|---|
| 1258 | + inode_unlock(dir); |
|---|
| 1259 | + |
|---|
| 1260 | + return err; |
|---|
| 1261 | +} |
|---|
| 1262 | + |
|---|
| 1263 | +static struct dentry *ovl_lookup_or_create(struct dentry *parent, |
|---|
| 1264 | + const char *name, umode_t mode) |
|---|
| 1265 | +{ |
|---|
| 1266 | + size_t len = strlen(name); |
|---|
| 1267 | + struct dentry *child; |
|---|
| 1268 | + |
|---|
| 1269 | + inode_lock_nested(parent->d_inode, I_MUTEX_PARENT); |
|---|
| 1270 | + child = lookup_one_len(name, parent, len); |
|---|
| 1271 | + if (!IS_ERR(child) && !child->d_inode) |
|---|
| 1272 | + child = ovl_create_real(parent->d_inode, child, |
|---|
| 1273 | + OVL_CATTR(mode)); |
|---|
| 1274 | + inode_unlock(parent->d_inode); |
|---|
| 1275 | + dput(parent); |
|---|
| 1276 | + |
|---|
| 1277 | + return child; |
|---|
| 1278 | +} |
|---|
| 1279 | + |
|---|
| 1280 | +/* |
|---|
| 1281 | + * Creates $workdir/work/incompat/volatile/dirty file if it is not already |
|---|
| 1282 | + * present. |
|---|
| 1283 | + */ |
|---|
| 1284 | +static int ovl_create_volatile_dirty(struct ovl_fs *ofs) |
|---|
| 1285 | +{ |
|---|
| 1286 | + unsigned int ctr; |
|---|
| 1287 | + struct dentry *d = dget(ofs->workbasedir); |
|---|
| 1288 | + static const char *const volatile_path[] = { |
|---|
| 1289 | + OVL_WORKDIR_NAME, "incompat", "volatile", "dirty" |
|---|
| 1290 | + }; |
|---|
| 1291 | + const char *const *name = volatile_path; |
|---|
| 1292 | + |
|---|
| 1293 | + for (ctr = ARRAY_SIZE(volatile_path); ctr; ctr--, name++) { |
|---|
| 1294 | + d = ovl_lookup_or_create(d, *name, ctr > 1 ? S_IFDIR : S_IFREG); |
|---|
| 1295 | + if (IS_ERR(d)) |
|---|
| 1296 | + return PTR_ERR(d); |
|---|
| 1297 | + } |
|---|
| 1298 | + dput(d); |
|---|
| 1299 | + return 0; |
|---|
| 1300 | +} |
|---|
| 1301 | + |
|---|
| 1126 | 1302 | static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs, |
|---|
| 1127 | 1303 | struct path *workpath) |
|---|
| 1128 | 1304 | { |
|---|
| 1129 | | - struct vfsmount *mnt = ofs->upper_mnt; |
|---|
| 1130 | | - struct dentry *temp; |
|---|
| 1305 | + struct vfsmount *mnt = ovl_upper_mnt(ofs); |
|---|
| 1306 | + struct dentry *temp, *workdir; |
|---|
| 1307 | + bool rename_whiteout; |
|---|
| 1308 | + bool d_type; |
|---|
| 1131 | 1309 | int fh_type; |
|---|
| 1132 | 1310 | int err; |
|---|
| 1133 | 1311 | |
|---|
| .. | .. |
|---|
| 1135 | 1313 | if (err) |
|---|
| 1136 | 1314 | return err; |
|---|
| 1137 | 1315 | |
|---|
| 1138 | | - ofs->workdir = ovl_workdir_create(ofs, OVL_WORKDIR_NAME, false); |
|---|
| 1139 | | - if (!ofs->workdir) |
|---|
| 1316 | + workdir = ovl_workdir_create(ofs, OVL_WORKDIR_NAME, false); |
|---|
| 1317 | + err = PTR_ERR(workdir); |
|---|
| 1318 | + if (IS_ERR_OR_NULL(workdir)) |
|---|
| 1140 | 1319 | goto out; |
|---|
| 1320 | + |
|---|
| 1321 | + ofs->workdir = workdir; |
|---|
| 1141 | 1322 | |
|---|
| 1142 | 1323 | err = ovl_setup_trap(sb, ofs->workdir, &ofs->workdir_trap, "workdir"); |
|---|
| 1143 | 1324 | if (err) |
|---|
| .. | .. |
|---|
| 1153 | 1334 | if (err < 0) |
|---|
| 1154 | 1335 | goto out; |
|---|
| 1155 | 1336 | |
|---|
| 1156 | | - /* |
|---|
| 1157 | | - * We allowed this configuration and don't want to break users over |
|---|
| 1158 | | - * kernel upgrade. So warn instead of erroring out. |
|---|
| 1159 | | - */ |
|---|
| 1160 | | - if (!err) |
|---|
| 1161 | | - pr_warn("overlayfs: upper fs needs to support d_type.\n"); |
|---|
| 1337 | + d_type = err; |
|---|
| 1338 | + if (!d_type) |
|---|
| 1339 | + pr_warn("upper fs needs to support d_type.\n"); |
|---|
| 1162 | 1340 | |
|---|
| 1163 | 1341 | /* Check if upper/work fs supports O_TMPFILE */ |
|---|
| 1164 | 1342 | temp = ovl_do_tmpfile(ofs->workdir, S_IFREG | 0); |
|---|
| .. | .. |
|---|
| 1166 | 1344 | if (ofs->tmpfile) |
|---|
| 1167 | 1345 | dput(temp); |
|---|
| 1168 | 1346 | else |
|---|
| 1169 | | - pr_warn("overlayfs: upper fs does not support tmpfile.\n"); |
|---|
| 1347 | + pr_warn("upper fs does not support tmpfile.\n"); |
|---|
| 1348 | + |
|---|
| 1349 | + |
|---|
| 1350 | + /* Check if upper/work fs supports RENAME_WHITEOUT */ |
|---|
| 1351 | + err = ovl_check_rename_whiteout(ofs->workdir); |
|---|
| 1352 | + if (err < 0) |
|---|
| 1353 | + goto out; |
|---|
| 1354 | + |
|---|
| 1355 | + rename_whiteout = err; |
|---|
| 1356 | + if (!rename_whiteout) |
|---|
| 1357 | + pr_warn("upper fs does not support RENAME_WHITEOUT.\n"); |
|---|
| 1170 | 1358 | |
|---|
| 1171 | 1359 | /* |
|---|
| 1172 | 1360 | * Check if upper/work fs supports trusted.overlay.* xattr |
|---|
| 1173 | 1361 | */ |
|---|
| 1174 | | - err = ovl_do_setxattr(ofs->workdir, OVL_XATTR_OPAQUE, "0", 1, 0); |
|---|
| 1362 | + err = ovl_do_setxattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE, "0", 1); |
|---|
| 1175 | 1363 | if (err) { |
|---|
| 1176 | 1364 | ofs->noxattr = true; |
|---|
| 1177 | 1365 | ofs->config.index = false; |
|---|
| 1178 | 1366 | ofs->config.metacopy = false; |
|---|
| 1179 | | - pr_warn("overlayfs: upper fs does not support xattr, falling back to index=off and metacopy=off.\n"); |
|---|
| 1367 | + pr_warn("upper fs does not support xattr, falling back to index=off and metacopy=off.\n"); |
|---|
| 1180 | 1368 | err = 0; |
|---|
| 1181 | 1369 | } else { |
|---|
| 1182 | | - vfs_removexattr(ofs->workdir, OVL_XATTR_OPAQUE); |
|---|
| 1370 | + ovl_do_removexattr(ofs, ofs->workdir, OVL_XATTR_OPAQUE); |
|---|
| 1371 | + } |
|---|
| 1372 | + |
|---|
| 1373 | + /* |
|---|
| 1374 | + * We allowed sub-optimal upper fs configuration and don't want to break |
|---|
| 1375 | + * users over kernel upgrade, but we never allowed remote upper fs, so |
|---|
| 1376 | + * we can enforce strict requirements for remote upper fs. |
|---|
| 1377 | + */ |
|---|
| 1378 | + if (ovl_dentry_remote(ofs->workdir) && |
|---|
| 1379 | + (!d_type || !rename_whiteout || ofs->noxattr)) { |
|---|
| 1380 | + pr_err("upper fs missing required features.\n"); |
|---|
| 1381 | + err = -EINVAL; |
|---|
| 1382 | + goto out; |
|---|
| 1383 | + } |
|---|
| 1384 | + |
|---|
| 1385 | + /* |
|---|
| 1386 | + * For volatile mount, create a incompat/volatile/dirty file to keep |
|---|
| 1387 | + * track of it. |
|---|
| 1388 | + */ |
|---|
| 1389 | + if (ofs->config.ovl_volatile) { |
|---|
| 1390 | + err = ovl_create_volatile_dirty(ofs); |
|---|
| 1391 | + if (err < 0) { |
|---|
| 1392 | + pr_err("Failed to create volatile/dirty file.\n"); |
|---|
| 1393 | + goto out; |
|---|
| 1394 | + } |
|---|
| 1183 | 1395 | } |
|---|
| 1184 | 1396 | |
|---|
| 1185 | 1397 | /* Check if upper/work fs supports file handles */ |
|---|
| 1186 | 1398 | fh_type = ovl_can_decode_fh(ofs->workdir->d_sb); |
|---|
| 1187 | 1399 | if (ofs->config.index && !fh_type) { |
|---|
| 1188 | 1400 | ofs->config.index = false; |
|---|
| 1189 | | - pr_warn("overlayfs: upper fs does not support file handles, falling back to index=off.\n"); |
|---|
| 1401 | + pr_warn("upper fs does not support file handles, falling back to index=off.\n"); |
|---|
| 1190 | 1402 | } |
|---|
| 1191 | 1403 | |
|---|
| 1192 | 1404 | /* Check if upper fs has 32bit inode numbers */ |
|---|
| 1193 | 1405 | if (fh_type != FILEID_INO32_GEN) |
|---|
| 1194 | | - ofs->xino_bits = 0; |
|---|
| 1406 | + ofs->xino_mode = -1; |
|---|
| 1195 | 1407 | |
|---|
| 1196 | 1408 | /* NFS export of r/w mount depends on index */ |
|---|
| 1197 | 1409 | if (ofs->config.nfs_export && !ofs->config.index) { |
|---|
| 1198 | | - pr_warn("overlayfs: NFS export requires \"index=on\", falling back to nfs_export=off.\n"); |
|---|
| 1410 | + pr_warn("NFS export requires \"index=on\", falling back to nfs_export=off.\n"); |
|---|
| 1199 | 1411 | ofs->config.nfs_export = false; |
|---|
| 1200 | 1412 | } |
|---|
| 1201 | 1413 | out: |
|---|
| .. | .. |
|---|
| 1215 | 1427 | |
|---|
| 1216 | 1428 | err = -EINVAL; |
|---|
| 1217 | 1429 | if (upperpath->mnt != workpath.mnt) { |
|---|
| 1218 | | - pr_err("overlayfs: workdir and upperdir must reside under the same mount\n"); |
|---|
| 1430 | + pr_err("workdir and upperdir must reside under the same mount\n"); |
|---|
| 1219 | 1431 | goto out; |
|---|
| 1220 | 1432 | } |
|---|
| 1221 | 1433 | if (!ovl_workdir_ok(workpath.dentry, upperpath->dentry)) { |
|---|
| 1222 | | - pr_err("overlayfs: workdir and upperdir must be separate subtrees\n"); |
|---|
| 1434 | + pr_err("workdir and upperdir must be separate subtrees\n"); |
|---|
| 1223 | 1435 | goto out; |
|---|
| 1224 | 1436 | } |
|---|
| 1225 | 1437 | |
|---|
| .. | .. |
|---|
| 1249 | 1461 | static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs, |
|---|
| 1250 | 1462 | struct ovl_entry *oe, struct path *upperpath) |
|---|
| 1251 | 1463 | { |
|---|
| 1252 | | - struct vfsmount *mnt = ofs->upper_mnt; |
|---|
| 1464 | + struct vfsmount *mnt = ovl_upper_mnt(ofs); |
|---|
| 1465 | + struct dentry *indexdir; |
|---|
| 1253 | 1466 | int err; |
|---|
| 1254 | 1467 | |
|---|
| 1255 | 1468 | err = mnt_want_write(mnt); |
|---|
| .. | .. |
|---|
| 1257 | 1470 | return err; |
|---|
| 1258 | 1471 | |
|---|
| 1259 | 1472 | /* Verify lower root is upper root origin */ |
|---|
| 1260 | | - err = ovl_verify_origin(upperpath->dentry, oe->lowerstack[0].dentry, |
|---|
| 1261 | | - true); |
|---|
| 1473 | + err = ovl_verify_origin(ofs, upperpath->dentry, |
|---|
| 1474 | + oe->lowerstack[0].dentry, true); |
|---|
| 1262 | 1475 | if (err) { |
|---|
| 1263 | | - pr_err("overlayfs: failed to verify upper root origin\n"); |
|---|
| 1476 | + pr_err("failed to verify upper root origin\n"); |
|---|
| 1264 | 1477 | goto out; |
|---|
| 1265 | 1478 | } |
|---|
| 1266 | 1479 | |
|---|
| 1267 | | - ofs->indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true); |
|---|
| 1268 | | - if (ofs->indexdir) { |
|---|
| 1480 | + /* index dir will act also as workdir */ |
|---|
| 1481 | + iput(ofs->workdir_trap); |
|---|
| 1482 | + ofs->workdir_trap = NULL; |
|---|
| 1483 | + dput(ofs->workdir); |
|---|
| 1484 | + ofs->workdir = NULL; |
|---|
| 1485 | + indexdir = ovl_workdir_create(ofs, OVL_INDEXDIR_NAME, true); |
|---|
| 1486 | + if (IS_ERR(indexdir)) { |
|---|
| 1487 | + err = PTR_ERR(indexdir); |
|---|
| 1488 | + } else if (indexdir) { |
|---|
| 1489 | + ofs->indexdir = indexdir; |
|---|
| 1490 | + ofs->workdir = dget(indexdir); |
|---|
| 1491 | + |
|---|
| 1269 | 1492 | err = ovl_setup_trap(sb, ofs->indexdir, &ofs->indexdir_trap, |
|---|
| 1270 | 1493 | "indexdir"); |
|---|
| 1271 | 1494 | if (err) |
|---|
| .. | .. |
|---|
| 1279 | 1502 | * "trusted.overlay.upper" to indicate that index may have |
|---|
| 1280 | 1503 | * directory entries. |
|---|
| 1281 | 1504 | */ |
|---|
| 1282 | | - if (ovl_check_origin_xattr(ofs->indexdir)) { |
|---|
| 1283 | | - err = ovl_verify_set_fh(ofs->indexdir, OVL_XATTR_ORIGIN, |
|---|
| 1505 | + if (ovl_check_origin_xattr(ofs, ofs->indexdir)) { |
|---|
| 1506 | + err = ovl_verify_set_fh(ofs, ofs->indexdir, |
|---|
| 1507 | + OVL_XATTR_ORIGIN, |
|---|
| 1284 | 1508 | upperpath->dentry, true, false); |
|---|
| 1285 | 1509 | if (err) |
|---|
| 1286 | | - pr_err("overlayfs: failed to verify index dir 'origin' xattr\n"); |
|---|
| 1510 | + pr_err("failed to verify index dir 'origin' xattr\n"); |
|---|
| 1287 | 1511 | } |
|---|
| 1288 | | - err = ovl_verify_upper(ofs->indexdir, upperpath->dentry, true); |
|---|
| 1512 | + err = ovl_verify_upper(ofs, ofs->indexdir, upperpath->dentry, |
|---|
| 1513 | + true); |
|---|
| 1289 | 1514 | if (err) |
|---|
| 1290 | | - pr_err("overlayfs: failed to verify index dir 'upper' xattr\n"); |
|---|
| 1515 | + pr_err("failed to verify index dir 'upper' xattr\n"); |
|---|
| 1291 | 1516 | |
|---|
| 1292 | 1517 | /* Cleanup bad/stale/orphan index entries */ |
|---|
| 1293 | 1518 | if (!err) |
|---|
| 1294 | 1519 | err = ovl_indexdir_cleanup(ofs); |
|---|
| 1295 | 1520 | } |
|---|
| 1296 | 1521 | if (err || !ofs->indexdir) |
|---|
| 1297 | | - pr_warn("overlayfs: try deleting index dir or mounting with '-o index=off' to disable inodes index.\n"); |
|---|
| 1522 | + pr_warn("try deleting index dir or mounting with '-o index=off' to disable inodes index.\n"); |
|---|
| 1298 | 1523 | |
|---|
| 1299 | 1524 | out: |
|---|
| 1300 | 1525 | mnt_drop_write(mnt); |
|---|
| 1301 | 1526 | return err; |
|---|
| 1302 | 1527 | } |
|---|
| 1303 | 1528 | |
|---|
| 1304 | | -/* Get a unique fsid for the layer */ |
|---|
| 1305 | | -static int ovl_get_fsid(struct ovl_fs *ofs, struct super_block *sb) |
|---|
| 1529 | +static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid) |
|---|
| 1306 | 1530 | { |
|---|
| 1531 | + unsigned int i; |
|---|
| 1532 | + |
|---|
| 1533 | + if (!ofs->config.nfs_export && !ovl_upper_mnt(ofs)) |
|---|
| 1534 | + return true; |
|---|
| 1535 | + |
|---|
| 1536 | + /* |
|---|
| 1537 | + * We allow using single lower with null uuid for index and nfs_export |
|---|
| 1538 | + * for example to support those features with single lower squashfs. |
|---|
| 1539 | + * To avoid regressions in setups of overlay with re-formatted lower |
|---|
| 1540 | + * squashfs, do not allow decoding origin with lower null uuid unless |
|---|
| 1541 | + * user opted-in to one of the new features that require following the |
|---|
| 1542 | + * lower inode of non-dir upper. |
|---|
| 1543 | + */ |
|---|
| 1544 | + if (!ofs->config.index && !ofs->config.metacopy && !ofs->config.xino && |
|---|
| 1545 | + uuid_is_null(uuid)) |
|---|
| 1546 | + return false; |
|---|
| 1547 | + |
|---|
| 1548 | + for (i = 0; i < ofs->numfs; i++) { |
|---|
| 1549 | + /* |
|---|
| 1550 | + * We use uuid to associate an overlay lower file handle with a |
|---|
| 1551 | + * lower layer, so we can accept lower fs with null uuid as long |
|---|
| 1552 | + * as all lower layers with null uuid are on the same fs. |
|---|
| 1553 | + * if we detect multiple lower fs with the same uuid, we |
|---|
| 1554 | + * disable lower file handle decoding on all of them. |
|---|
| 1555 | + */ |
|---|
| 1556 | + if (ofs->fs[i].is_lower && |
|---|
| 1557 | + uuid_equal(&ofs->fs[i].sb->s_uuid, uuid)) { |
|---|
| 1558 | + ofs->fs[i].bad_uuid = true; |
|---|
| 1559 | + return false; |
|---|
| 1560 | + } |
|---|
| 1561 | + } |
|---|
| 1562 | + return true; |
|---|
| 1563 | +} |
|---|
| 1564 | + |
|---|
| 1565 | +/* Get a unique fsid for the layer */ |
|---|
| 1566 | +static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) |
|---|
| 1567 | +{ |
|---|
| 1568 | + struct super_block *sb = path->mnt->mnt_sb; |
|---|
| 1307 | 1569 | unsigned int i; |
|---|
| 1308 | 1570 | dev_t dev; |
|---|
| 1309 | 1571 | int err; |
|---|
| 1572 | + bool bad_uuid = false; |
|---|
| 1310 | 1573 | |
|---|
| 1311 | | - /* fsid 0 is reserved for upper fs even with non upper overlay */ |
|---|
| 1312 | | - if (ofs->upper_mnt && ofs->upper_mnt->mnt_sb == sb) |
|---|
| 1313 | | - return 0; |
|---|
| 1574 | + for (i = 0; i < ofs->numfs; i++) { |
|---|
| 1575 | + if (ofs->fs[i].sb == sb) |
|---|
| 1576 | + return i; |
|---|
| 1577 | + } |
|---|
| 1314 | 1578 | |
|---|
| 1315 | | - for (i = 0; i < ofs->numlowerfs; i++) { |
|---|
| 1316 | | - if (ofs->lower_fs[i].sb == sb) |
|---|
| 1317 | | - return i + 1; |
|---|
| 1579 | + if (!ovl_lower_uuid_ok(ofs, &sb->s_uuid)) { |
|---|
| 1580 | + bad_uuid = true; |
|---|
| 1581 | + if (ofs->config.index || ofs->config.nfs_export) { |
|---|
| 1582 | + ofs->config.index = false; |
|---|
| 1583 | + ofs->config.nfs_export = false; |
|---|
| 1584 | + pr_warn("%s uuid detected in lower fs '%pd2', falling back to index=off,nfs_export=off.\n", |
|---|
| 1585 | + uuid_is_null(&sb->s_uuid) ? "null" : |
|---|
| 1586 | + "conflicting", |
|---|
| 1587 | + path->dentry); |
|---|
| 1588 | + } |
|---|
| 1318 | 1589 | } |
|---|
| 1319 | 1590 | |
|---|
| 1320 | 1591 | err = get_anon_bdev(&dev); |
|---|
| 1321 | 1592 | if (err) { |
|---|
| 1322 | | - pr_err("overlayfs: failed to get anonymous bdev for lowerpath\n"); |
|---|
| 1593 | + pr_err("failed to get anonymous bdev for lowerpath\n"); |
|---|
| 1323 | 1594 | return err; |
|---|
| 1324 | 1595 | } |
|---|
| 1325 | 1596 | |
|---|
| 1326 | | - ofs->lower_fs[ofs->numlowerfs].sb = sb; |
|---|
| 1327 | | - ofs->lower_fs[ofs->numlowerfs].pseudo_dev = dev; |
|---|
| 1328 | | - ofs->numlowerfs++; |
|---|
| 1597 | + ofs->fs[ofs->numfs].sb = sb; |
|---|
| 1598 | + ofs->fs[ofs->numfs].pseudo_dev = dev; |
|---|
| 1599 | + ofs->fs[ofs->numfs].bad_uuid = bad_uuid; |
|---|
| 1329 | 1600 | |
|---|
| 1330 | | - return ofs->numlowerfs; |
|---|
| 1601 | + return ofs->numfs++; |
|---|
| 1331 | 1602 | } |
|---|
| 1332 | 1603 | |
|---|
| 1333 | | -static int ovl_get_lower_layers(struct super_block *sb, struct ovl_fs *ofs, |
|---|
| 1334 | | - struct path *stack, unsigned int numlower) |
|---|
| 1604 | +static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs, |
|---|
| 1605 | + struct path *stack, unsigned int numlower, |
|---|
| 1606 | + struct ovl_layer *layers) |
|---|
| 1335 | 1607 | { |
|---|
| 1336 | 1608 | int err; |
|---|
| 1337 | 1609 | unsigned int i; |
|---|
| 1338 | 1610 | |
|---|
| 1339 | 1611 | err = -ENOMEM; |
|---|
| 1340 | | - ofs->lower_layers = kcalloc(numlower, sizeof(struct ovl_layer), |
|---|
| 1341 | | - GFP_KERNEL); |
|---|
| 1342 | | - if (ofs->lower_layers == NULL) |
|---|
| 1612 | + ofs->fs = kcalloc(numlower + 1, sizeof(struct ovl_sb), GFP_KERNEL); |
|---|
| 1613 | + if (ofs->fs == NULL) |
|---|
| 1343 | 1614 | goto out; |
|---|
| 1344 | 1615 | |
|---|
| 1345 | | - ofs->lower_fs = kcalloc(numlower, sizeof(struct ovl_sb), |
|---|
| 1346 | | - GFP_KERNEL); |
|---|
| 1347 | | - if (ofs->lower_fs == NULL) |
|---|
| 1616 | + /* idx/fsid 0 are reserved for upper fs even with lower only overlay */ |
|---|
| 1617 | + ofs->numfs++; |
|---|
| 1618 | + |
|---|
| 1619 | + /* |
|---|
| 1620 | + * All lower layers that share the same fs as upper layer, use the same |
|---|
| 1621 | + * pseudo_dev as upper layer. Allocate fs[0].pseudo_dev even for lower |
|---|
| 1622 | + * only overlay to simplify ovl_fs_free(). |
|---|
| 1623 | + * is_lower will be set if upper fs is shared with a lower layer. |
|---|
| 1624 | + */ |
|---|
| 1625 | + err = get_anon_bdev(&ofs->fs[0].pseudo_dev); |
|---|
| 1626 | + if (err) { |
|---|
| 1627 | + pr_err("failed to get anonymous bdev for upper fs\n"); |
|---|
| 1348 | 1628 | goto out; |
|---|
| 1629 | + } |
|---|
| 1630 | + |
|---|
| 1631 | + if (ovl_upper_mnt(ofs)) { |
|---|
| 1632 | + ofs->fs[0].sb = ovl_upper_mnt(ofs)->mnt_sb; |
|---|
| 1633 | + ofs->fs[0].is_lower = false; |
|---|
| 1634 | + } |
|---|
| 1349 | 1635 | |
|---|
| 1350 | 1636 | for (i = 0; i < numlower; i++) { |
|---|
| 1351 | 1637 | struct vfsmount *mnt; |
|---|
| 1352 | 1638 | struct inode *trap; |
|---|
| 1353 | 1639 | int fsid; |
|---|
| 1354 | 1640 | |
|---|
| 1355 | | - err = fsid = ovl_get_fsid(ofs, stack[i].mnt->mnt_sb); |
|---|
| 1641 | + err = fsid = ovl_get_fsid(ofs, &stack[i]); |
|---|
| 1356 | 1642 | if (err < 0) |
|---|
| 1357 | 1643 | goto out; |
|---|
| 1358 | 1644 | |
|---|
| .. | .. |
|---|
| 1378 | 1664 | mnt = clone_private_mount(&stack[i]); |
|---|
| 1379 | 1665 | err = PTR_ERR(mnt); |
|---|
| 1380 | 1666 | if (IS_ERR(mnt)) { |
|---|
| 1381 | | - pr_err("overlayfs: failed to clone lowerpath\n"); |
|---|
| 1667 | + pr_err("failed to clone lowerpath\n"); |
|---|
| 1382 | 1668 | iput(trap); |
|---|
| 1383 | 1669 | goto out; |
|---|
| 1384 | 1670 | } |
|---|
| .. | .. |
|---|
| 1389 | 1675 | */ |
|---|
| 1390 | 1676 | mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME; |
|---|
| 1391 | 1677 | |
|---|
| 1392 | | - ofs->lower_layers[ofs->numlower].trap = trap; |
|---|
| 1393 | | - ofs->lower_layers[ofs->numlower].mnt = mnt; |
|---|
| 1394 | | - ofs->lower_layers[ofs->numlower].idx = i + 1; |
|---|
| 1395 | | - ofs->lower_layers[ofs->numlower].fsid = fsid; |
|---|
| 1396 | | - if (fsid) { |
|---|
| 1397 | | - ofs->lower_layers[ofs->numlower].fs = |
|---|
| 1398 | | - &ofs->lower_fs[fsid - 1]; |
|---|
| 1399 | | - } |
|---|
| 1400 | | - ofs->numlower++; |
|---|
| 1678 | + layers[ofs->numlayer].trap = trap; |
|---|
| 1679 | + layers[ofs->numlayer].mnt = mnt; |
|---|
| 1680 | + layers[ofs->numlayer].idx = ofs->numlayer; |
|---|
| 1681 | + layers[ofs->numlayer].fsid = fsid; |
|---|
| 1682 | + layers[ofs->numlayer].fs = &ofs->fs[fsid]; |
|---|
| 1683 | + ofs->numlayer++; |
|---|
| 1684 | + ofs->fs[fsid].is_lower = true; |
|---|
| 1401 | 1685 | } |
|---|
| 1402 | 1686 | |
|---|
| 1403 | 1687 | /* |
|---|
| 1404 | 1688 | * When all layers on same fs, overlay can use real inode numbers. |
|---|
| 1405 | | - * With mount option "xino=on", mounter declares that there are enough |
|---|
| 1406 | | - * free high bits in underlying fs to hold the unique fsid. |
|---|
| 1689 | + * With mount option "xino=<on|auto>", mounter declares that there are |
|---|
| 1690 | + * enough free high bits in underlying fs to hold the unique fsid. |
|---|
| 1407 | 1691 | * If overlayfs does encounter underlying inodes using the high xino |
|---|
| 1408 | 1692 | * bits reserved for fsid, it emits a warning and uses the original |
|---|
| 1409 | | - * inode number. |
|---|
| 1693 | + * inode number or a non persistent inode number allocated from a |
|---|
| 1694 | + * dedicated range. |
|---|
| 1410 | 1695 | */ |
|---|
| 1411 | | - if (!ofs->numlowerfs || (ofs->numlowerfs == 1 && !ofs->upper_mnt)) { |
|---|
| 1412 | | - ofs->xino_bits = 0; |
|---|
| 1413 | | - ofs->config.xino = OVL_XINO_OFF; |
|---|
| 1414 | | - } else if (ofs->config.xino == OVL_XINO_ON && !ofs->xino_bits) { |
|---|
| 1696 | + if (ofs->numfs - !ovl_upper_mnt(ofs) == 1) { |
|---|
| 1697 | + if (ofs->config.xino == OVL_XINO_ON) |
|---|
| 1698 | + pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n"); |
|---|
| 1699 | + ofs->xino_mode = 0; |
|---|
| 1700 | + } else if (ofs->config.xino == OVL_XINO_OFF) { |
|---|
| 1701 | + ofs->xino_mode = -1; |
|---|
| 1702 | + } else if (ofs->xino_mode < 0) { |
|---|
| 1415 | 1703 | /* |
|---|
| 1416 | | - * This is a roundup of number of bits needed for numlowerfs+1 |
|---|
| 1417 | | - * (i.e. ilog2(numlowerfs+1 - 1) + 1). fsid 0 is reserved for |
|---|
| 1418 | | - * upper fs even with non upper overlay. |
|---|
| 1704 | + * This is a roundup of number of bits needed for encoding |
|---|
| 1705 | + * fsid, where fsid 0 is reserved for upper fs (even with |
|---|
| 1706 | + * lower only overlay) +1 extra bit is reserved for the non |
|---|
| 1707 | + * persistent inode number range that is used for resolving |
|---|
| 1708 | + * xino lower bits overflow. |
|---|
| 1419 | 1709 | */ |
|---|
| 1420 | | - BUILD_BUG_ON(ilog2(OVL_MAX_STACK) > 31); |
|---|
| 1421 | | - ofs->xino_bits = ilog2(ofs->numlowerfs) + 1; |
|---|
| 1710 | + BUILD_BUG_ON(ilog2(OVL_MAX_STACK) > 30); |
|---|
| 1711 | + ofs->xino_mode = ilog2(ofs->numfs - 1) + 2; |
|---|
| 1422 | 1712 | } |
|---|
| 1423 | 1713 | |
|---|
| 1424 | | - if (ofs->xino_bits) { |
|---|
| 1425 | | - pr_info("overlayfs: \"xino\" feature enabled using %d upper inode bits.\n", |
|---|
| 1426 | | - ofs->xino_bits); |
|---|
| 1714 | + if (ofs->xino_mode > 0) { |
|---|
| 1715 | + pr_info("\"xino\" feature enabled using %d upper inode bits.\n", |
|---|
| 1716 | + ofs->xino_mode); |
|---|
| 1427 | 1717 | } |
|---|
| 1428 | 1718 | |
|---|
| 1429 | 1719 | err = 0; |
|---|
| .. | .. |
|---|
| 1432 | 1722 | } |
|---|
| 1433 | 1723 | |
|---|
| 1434 | 1724 | static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb, |
|---|
| 1435 | | - struct ovl_fs *ofs) |
|---|
| 1725 | + const char *lower, unsigned int numlower, |
|---|
| 1726 | + struct ovl_fs *ofs, struct ovl_layer *layers) |
|---|
| 1436 | 1727 | { |
|---|
| 1437 | 1728 | int err; |
|---|
| 1438 | | - char *lowertmp, *lower; |
|---|
| 1439 | 1729 | struct path *stack = NULL; |
|---|
| 1440 | | - unsigned int stacklen, numlower = 0, i; |
|---|
| 1441 | | - bool remote = false; |
|---|
| 1730 | + unsigned int i; |
|---|
| 1442 | 1731 | struct ovl_entry *oe; |
|---|
| 1443 | 1732 | |
|---|
| 1444 | | - err = -ENOMEM; |
|---|
| 1445 | | - lowertmp = kstrdup(ofs->config.lowerdir, GFP_KERNEL); |
|---|
| 1446 | | - if (!lowertmp) |
|---|
| 1447 | | - goto out_err; |
|---|
| 1448 | | - |
|---|
| 1449 | | - err = -EINVAL; |
|---|
| 1450 | | - stacklen = ovl_split_lowerdirs(lowertmp); |
|---|
| 1451 | | - if (stacklen > OVL_MAX_STACK) { |
|---|
| 1452 | | - pr_err("overlayfs: too many lower directories, limit is %d\n", |
|---|
| 1453 | | - OVL_MAX_STACK); |
|---|
| 1454 | | - goto out_err; |
|---|
| 1455 | | - } else if (!ofs->config.upperdir && stacklen == 1) { |
|---|
| 1456 | | - pr_err("overlayfs: at least 2 lowerdir are needed while upperdir nonexistent\n"); |
|---|
| 1457 | | - goto out_err; |
|---|
| 1458 | | - } else if (!ofs->config.upperdir && ofs->config.nfs_export && |
|---|
| 1459 | | - ofs->config.redirect_follow) { |
|---|
| 1460 | | - pr_warn("overlayfs: NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n"); |
|---|
| 1461 | | - ofs->config.nfs_export = false; |
|---|
| 1733 | + if (!ofs->config.upperdir && numlower == 1) { |
|---|
| 1734 | + pr_err("at least 2 lowerdir are needed while upperdir nonexistent\n"); |
|---|
| 1735 | + return ERR_PTR(-EINVAL); |
|---|
| 1462 | 1736 | } |
|---|
| 1463 | 1737 | |
|---|
| 1464 | | - err = -ENOMEM; |
|---|
| 1465 | | - stack = kcalloc(stacklen, sizeof(struct path), GFP_KERNEL); |
|---|
| 1738 | + stack = kcalloc(numlower, sizeof(struct path), GFP_KERNEL); |
|---|
| 1466 | 1739 | if (!stack) |
|---|
| 1467 | | - goto out_err; |
|---|
| 1740 | + return ERR_PTR(-ENOMEM); |
|---|
| 1468 | 1741 | |
|---|
| 1469 | 1742 | err = -EINVAL; |
|---|
| 1470 | | - lower = lowertmp; |
|---|
| 1471 | | - for (numlower = 0; numlower < stacklen; numlower++) { |
|---|
| 1472 | | - err = ovl_lower_dir(lower, &stack[numlower], ofs, |
|---|
| 1473 | | - &sb->s_stack_depth, &remote); |
|---|
| 1743 | + for (i = 0; i < numlower; i++) { |
|---|
| 1744 | + err = ovl_lower_dir(lower, &stack[i], ofs, &sb->s_stack_depth); |
|---|
| 1474 | 1745 | if (err) |
|---|
| 1475 | 1746 | goto out_err; |
|---|
| 1476 | 1747 | |
|---|
| .. | .. |
|---|
| 1480 | 1751 | err = -EINVAL; |
|---|
| 1481 | 1752 | sb->s_stack_depth++; |
|---|
| 1482 | 1753 | if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { |
|---|
| 1483 | | - pr_err("overlayfs: maximum fs stacking depth exceeded\n"); |
|---|
| 1754 | + pr_err("maximum fs stacking depth exceeded\n"); |
|---|
| 1484 | 1755 | goto out_err; |
|---|
| 1485 | 1756 | } |
|---|
| 1486 | 1757 | |
|---|
| 1487 | | - err = ovl_get_lower_layers(sb, ofs, stack, numlower); |
|---|
| 1758 | + err = ovl_get_layers(sb, ofs, stack, numlower, layers); |
|---|
| 1488 | 1759 | if (err) |
|---|
| 1489 | 1760 | goto out_err; |
|---|
| 1490 | 1761 | |
|---|
| .. | .. |
|---|
| 1495 | 1766 | |
|---|
| 1496 | 1767 | for (i = 0; i < numlower; i++) { |
|---|
| 1497 | 1768 | oe->lowerstack[i].dentry = dget(stack[i].dentry); |
|---|
| 1498 | | - oe->lowerstack[i].layer = &ofs->lower_layers[i]; |
|---|
| 1769 | + oe->lowerstack[i].layer = &ofs->layers[i+1]; |
|---|
| 1499 | 1770 | } |
|---|
| 1500 | | - |
|---|
| 1501 | | - if (remote) |
|---|
| 1502 | | - sb->s_d_op = &ovl_reval_dentry_operations; |
|---|
| 1503 | | - else |
|---|
| 1504 | | - sb->s_d_op = &ovl_dentry_operations; |
|---|
| 1505 | 1771 | |
|---|
| 1506 | 1772 | out: |
|---|
| 1507 | 1773 | for (i = 0; i < numlower; i++) |
|---|
| 1508 | 1774 | path_put(&stack[i]); |
|---|
| 1509 | 1775 | kfree(stack); |
|---|
| 1510 | | - kfree(lowertmp); |
|---|
| 1511 | 1776 | |
|---|
| 1512 | 1777 | return oe; |
|---|
| 1513 | 1778 | |
|---|
| .. | .. |
|---|
| 1537 | 1802 | while (!err && parent != next) { |
|---|
| 1538 | 1803 | if (is_lower && ovl_lookup_trap_inode(sb, parent)) { |
|---|
| 1539 | 1804 | err = -ELOOP; |
|---|
| 1540 | | - pr_err("overlayfs: overlapping %s path\n", name); |
|---|
| 1805 | + pr_err("overlapping %s path\n", name); |
|---|
| 1541 | 1806 | } else if (ovl_is_inuse(parent)) { |
|---|
| 1542 | 1807 | err = ovl_report_in_use(ofs, name); |
|---|
| 1543 | 1808 | } |
|---|
| .. | .. |
|---|
| 1559 | 1824 | { |
|---|
| 1560 | 1825 | int i, err; |
|---|
| 1561 | 1826 | |
|---|
| 1562 | | - if (ofs->upper_mnt) { |
|---|
| 1563 | | - err = ovl_check_layer(sb, ofs, ofs->upper_mnt->mnt_root, |
|---|
| 1827 | + if (ovl_upper_mnt(ofs)) { |
|---|
| 1828 | + err = ovl_check_layer(sb, ofs, ovl_upper_mnt(ofs)->mnt_root, |
|---|
| 1564 | 1829 | "upperdir", false); |
|---|
| 1565 | 1830 | if (err) |
|---|
| 1566 | 1831 | return err; |
|---|
| .. | .. |
|---|
| 1578 | 1843 | return err; |
|---|
| 1579 | 1844 | } |
|---|
| 1580 | 1845 | |
|---|
| 1581 | | - for (i = 0; i < ofs->numlower; i++) { |
|---|
| 1846 | + for (i = 1; i < ofs->numlayer; i++) { |
|---|
| 1582 | 1847 | err = ovl_check_layer(sb, ofs, |
|---|
| 1583 | | - ofs->lower_layers[i].mnt->mnt_root, |
|---|
| 1848 | + ofs->layers[i].mnt->mnt_root, |
|---|
| 1584 | 1849 | "lowerdir", true); |
|---|
| 1585 | 1850 | if (err) |
|---|
| 1586 | 1851 | return err; |
|---|
| .. | .. |
|---|
| 1589 | 1854 | return 0; |
|---|
| 1590 | 1855 | } |
|---|
| 1591 | 1856 | |
|---|
| 1857 | +static struct dentry *ovl_get_root(struct super_block *sb, |
|---|
| 1858 | + struct dentry *upperdentry, |
|---|
| 1859 | + struct ovl_entry *oe) |
|---|
| 1860 | +{ |
|---|
| 1861 | + struct dentry *root; |
|---|
| 1862 | + struct ovl_path *lowerpath = &oe->lowerstack[0]; |
|---|
| 1863 | + unsigned long ino = d_inode(lowerpath->dentry)->i_ino; |
|---|
| 1864 | + int fsid = lowerpath->layer->fsid; |
|---|
| 1865 | + struct ovl_inode_params oip = { |
|---|
| 1866 | + .upperdentry = upperdentry, |
|---|
| 1867 | + .lowerpath = lowerpath, |
|---|
| 1868 | + }; |
|---|
| 1869 | + |
|---|
| 1870 | + root = d_make_root(ovl_new_inode(sb, S_IFDIR, 0)); |
|---|
| 1871 | + if (!root) |
|---|
| 1872 | + return NULL; |
|---|
| 1873 | + |
|---|
| 1874 | + root->d_fsdata = oe; |
|---|
| 1875 | + |
|---|
| 1876 | + if (upperdentry) { |
|---|
| 1877 | + /* Root inode uses upper st_ino/i_ino */ |
|---|
| 1878 | + ino = d_inode(upperdentry)->i_ino; |
|---|
| 1879 | + fsid = 0; |
|---|
| 1880 | + ovl_dentry_set_upper_alias(root); |
|---|
| 1881 | + if (ovl_is_impuredir(sb, upperdentry)) |
|---|
| 1882 | + ovl_set_flag(OVL_IMPURE, d_inode(root)); |
|---|
| 1883 | + } |
|---|
| 1884 | + |
|---|
| 1885 | + /* Root is always merge -> can have whiteouts */ |
|---|
| 1886 | + ovl_set_flag(OVL_WHITEOUTS, d_inode(root)); |
|---|
| 1887 | + ovl_dentry_set_flag(OVL_E_CONNECTED, root); |
|---|
| 1888 | + ovl_set_upperdata(d_inode(root)); |
|---|
| 1889 | + ovl_inode_init(d_inode(root), &oip, ino, fsid); |
|---|
| 1890 | + ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE); |
|---|
| 1891 | + |
|---|
| 1892 | + return root; |
|---|
| 1893 | +} |
|---|
| 1894 | + |
|---|
| 1592 | 1895 | static int ovl_fill_super(struct super_block *sb, void *data, int silent) |
|---|
| 1593 | 1896 | { |
|---|
| 1594 | 1897 | struct path upperpath = { }; |
|---|
| 1595 | 1898 | struct dentry *root_dentry; |
|---|
| 1596 | 1899 | struct ovl_entry *oe; |
|---|
| 1597 | 1900 | struct ovl_fs *ofs; |
|---|
| 1901 | + struct ovl_layer *layers; |
|---|
| 1598 | 1902 | struct cred *cred; |
|---|
| 1903 | + char *splitlower = NULL; |
|---|
| 1904 | + unsigned int numlower; |
|---|
| 1599 | 1905 | int err; |
|---|
| 1906 | + |
|---|
| 1907 | + sb->s_d_op = &ovl_dentry_operations; |
|---|
| 1600 | 1908 | |
|---|
| 1601 | 1909 | err = -ENOMEM; |
|---|
| 1602 | 1910 | ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL); |
|---|
| .. | .. |
|---|
| 1606 | 1914 | ofs->creator_cred = cred = prepare_creds(); |
|---|
| 1607 | 1915 | if (!cred) |
|---|
| 1608 | 1916 | goto out_err; |
|---|
| 1917 | + |
|---|
| 1918 | + /* Is there a reason anyone would want not to share whiteouts? */ |
|---|
| 1919 | + ofs->share_whiteout = true; |
|---|
| 1609 | 1920 | |
|---|
| 1610 | 1921 | ofs->config.index = ovl_index_def; |
|---|
| 1611 | 1922 | ofs->config.nfs_export = ovl_nfs_export_def; |
|---|
| .. | .. |
|---|
| 1618 | 1929 | err = -EINVAL; |
|---|
| 1619 | 1930 | if (!ofs->config.lowerdir) { |
|---|
| 1620 | 1931 | if (!silent) |
|---|
| 1621 | | - pr_err("overlayfs: missing 'lowerdir'\n"); |
|---|
| 1932 | + pr_err("missing 'lowerdir'\n"); |
|---|
| 1622 | 1933 | goto out_err; |
|---|
| 1623 | 1934 | } |
|---|
| 1624 | 1935 | |
|---|
| 1936 | + err = -ENOMEM; |
|---|
| 1937 | + splitlower = kstrdup(ofs->config.lowerdir, GFP_KERNEL); |
|---|
| 1938 | + if (!splitlower) |
|---|
| 1939 | + goto out_err; |
|---|
| 1940 | + |
|---|
| 1941 | + numlower = ovl_split_lowerdirs(splitlower); |
|---|
| 1942 | + if (numlower > OVL_MAX_STACK) { |
|---|
| 1943 | + pr_err("too many lower directories, limit is %d\n", |
|---|
| 1944 | + OVL_MAX_STACK); |
|---|
| 1945 | + goto out_err; |
|---|
| 1946 | + } |
|---|
| 1947 | + |
|---|
| 1948 | + layers = kcalloc(numlower + 1, sizeof(struct ovl_layer), GFP_KERNEL); |
|---|
| 1949 | + if (!layers) |
|---|
| 1950 | + goto out_err; |
|---|
| 1951 | + |
|---|
| 1952 | + ofs->layers = layers; |
|---|
| 1953 | + /* Layer 0 is reserved for upper even if there's no upper */ |
|---|
| 1954 | + ofs->numlayer = 1; |
|---|
| 1955 | + |
|---|
| 1625 | 1956 | sb->s_stack_depth = 0; |
|---|
| 1626 | 1957 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
|---|
| 1958 | + atomic_long_set(&ofs->last_ino, 1); |
|---|
| 1627 | 1959 | /* Assume underlaying fs uses 32bit inodes unless proven otherwise */ |
|---|
| 1628 | | - if (ofs->config.xino != OVL_XINO_OFF) |
|---|
| 1629 | | - ofs->xino_bits = BITS_PER_LONG - 32; |
|---|
| 1960 | + if (ofs->config.xino != OVL_XINO_OFF) { |
|---|
| 1961 | + ofs->xino_mode = BITS_PER_LONG - 32; |
|---|
| 1962 | + if (!ofs->xino_mode) { |
|---|
| 1963 | + pr_warn("xino not supported on 32bit kernel, falling back to xino=off.\n"); |
|---|
| 1964 | + ofs->config.xino = OVL_XINO_OFF; |
|---|
| 1965 | + } |
|---|
| 1966 | + } |
|---|
| 1630 | 1967 | |
|---|
| 1631 | 1968 | /* alloc/destroy_inode needed for setting up traps in inode cache */ |
|---|
| 1632 | 1969 | sb->s_op = &ovl_super_operations; |
|---|
| 1633 | 1970 | |
|---|
| 1634 | 1971 | if (ofs->config.upperdir) { |
|---|
| 1972 | + struct super_block *upper_sb; |
|---|
| 1973 | + |
|---|
| 1635 | 1974 | if (!ofs->config.workdir) { |
|---|
| 1636 | | - pr_err("overlayfs: missing 'workdir'\n"); |
|---|
| 1975 | + pr_err("missing 'workdir'\n"); |
|---|
| 1637 | 1976 | goto out_err; |
|---|
| 1638 | 1977 | } |
|---|
| 1639 | 1978 | |
|---|
| 1640 | | - err = ovl_get_upper(sb, ofs, &upperpath); |
|---|
| 1979 | + err = ovl_get_upper(sb, ofs, &layers[0], &upperpath); |
|---|
| 1641 | 1980 | if (err) |
|---|
| 1642 | 1981 | goto out_err; |
|---|
| 1982 | + |
|---|
| 1983 | + upper_sb = ovl_upper_mnt(ofs)->mnt_sb; |
|---|
| 1984 | + if (!ovl_should_sync(ofs)) { |
|---|
| 1985 | + ofs->errseq = errseq_sample(&upper_sb->s_wb_err); |
|---|
| 1986 | + if (errseq_check(&upper_sb->s_wb_err, ofs->errseq)) { |
|---|
| 1987 | + err = -EIO; |
|---|
| 1988 | + pr_err("Cannot mount volatile when upperdir has an unseen error. Sync upperdir fs to clear state.\n"); |
|---|
| 1989 | + goto out_err; |
|---|
| 1990 | + } |
|---|
| 1991 | + } |
|---|
| 1643 | 1992 | |
|---|
| 1644 | 1993 | err = ovl_get_workdir(sb, ofs, &upperpath); |
|---|
| 1645 | 1994 | if (err) |
|---|
| .. | .. |
|---|
| 1648 | 1997 | if (!ofs->workdir) |
|---|
| 1649 | 1998 | sb->s_flags |= SB_RDONLY; |
|---|
| 1650 | 1999 | |
|---|
| 1651 | | - sb->s_stack_depth = ofs->upper_mnt->mnt_sb->s_stack_depth; |
|---|
| 1652 | | - sb->s_time_gran = ofs->upper_mnt->mnt_sb->s_time_gran; |
|---|
| 1653 | | - |
|---|
| 2000 | + sb->s_stack_depth = upper_sb->s_stack_depth; |
|---|
| 2001 | + sb->s_time_gran = upper_sb->s_time_gran; |
|---|
| 1654 | 2002 | } |
|---|
| 1655 | | - oe = ovl_get_lowerstack(sb, ofs); |
|---|
| 2003 | + oe = ovl_get_lowerstack(sb, splitlower, numlower, ofs, layers); |
|---|
| 1656 | 2004 | err = PTR_ERR(oe); |
|---|
| 1657 | 2005 | if (IS_ERR(oe)) |
|---|
| 1658 | 2006 | goto out_err; |
|---|
| 1659 | 2007 | |
|---|
| 1660 | 2008 | /* If the upper fs is nonexistent, we mark overlayfs r/o too */ |
|---|
| 1661 | | - if (!ofs->upper_mnt) |
|---|
| 2009 | + if (!ovl_upper_mnt(ofs)) |
|---|
| 1662 | 2010 | sb->s_flags |= SB_RDONLY; |
|---|
| 1663 | 2011 | |
|---|
| 1664 | | - if (!(ovl_force_readonly(ofs)) && ofs->config.index) { |
|---|
| 2012 | + if (!ovl_force_readonly(ofs) && ofs->config.index) { |
|---|
| 1665 | 2013 | err = ovl_get_indexdir(sb, ofs, oe, &upperpath); |
|---|
| 1666 | 2014 | if (err) |
|---|
| 1667 | 2015 | goto out_free_oe; |
|---|
| 1668 | 2016 | |
|---|
| 1669 | 2017 | /* Force r/o mount with no index dir */ |
|---|
| 1670 | | - if (!ofs->indexdir) { |
|---|
| 1671 | | - dput(ofs->workdir); |
|---|
| 1672 | | - ofs->workdir = NULL; |
|---|
| 2018 | + if (!ofs->indexdir) |
|---|
| 1673 | 2019 | sb->s_flags |= SB_RDONLY; |
|---|
| 1674 | | - } |
|---|
| 1675 | | - |
|---|
| 1676 | 2020 | } |
|---|
| 1677 | 2021 | |
|---|
| 1678 | 2022 | err = ovl_check_overlapping_layers(sb, ofs); |
|---|
| .. | .. |
|---|
| 1682 | 2026 | /* Show index=off in /proc/mounts for forced r/o mount */ |
|---|
| 1683 | 2027 | if (!ofs->indexdir) { |
|---|
| 1684 | 2028 | ofs->config.index = false; |
|---|
| 1685 | | - if (ofs->upper_mnt && ofs->config.nfs_export) { |
|---|
| 1686 | | - pr_warn("overlayfs: NFS export requires an index dir, falling back to nfs_export=off.\n"); |
|---|
| 2029 | + if (ovl_upper_mnt(ofs) && ofs->config.nfs_export) { |
|---|
| 2030 | + pr_warn("NFS export requires an index dir, falling back to nfs_export=off.\n"); |
|---|
| 1687 | 2031 | ofs->config.nfs_export = false; |
|---|
| 1688 | 2032 | } |
|---|
| 1689 | 2033 | } |
|---|
| 1690 | 2034 | |
|---|
| 1691 | 2035 | if (ofs->config.metacopy && ofs->config.nfs_export) { |
|---|
| 1692 | | - pr_warn("overlayfs: NFS export is not supported with metadata only copy up, falling back to nfs_export=off.\n"); |
|---|
| 2036 | + pr_warn("NFS export is not supported with metadata only copy up, falling back to nfs_export=off.\n"); |
|---|
| 1693 | 2037 | ofs->config.nfs_export = false; |
|---|
| 1694 | 2038 | } |
|---|
| 1695 | 2039 | |
|---|
| .. | .. |
|---|
| 1703 | 2047 | sb->s_xattr = ovl_xattr_handlers; |
|---|
| 1704 | 2048 | sb->s_fs_info = ofs; |
|---|
| 1705 | 2049 | sb->s_flags |= SB_POSIXACL; |
|---|
| 2050 | + sb->s_iflags |= SB_I_SKIP_SYNC; |
|---|
| 1706 | 2051 | |
|---|
| 1707 | 2052 | err = -ENOMEM; |
|---|
| 1708 | | - root_dentry = d_make_root(ovl_new_inode(sb, S_IFDIR, 0)); |
|---|
| 2053 | + root_dentry = ovl_get_root(sb, upperpath.dentry, oe); |
|---|
| 1709 | 2054 | if (!root_dentry) |
|---|
| 1710 | 2055 | goto out_free_oe; |
|---|
| 1711 | 2056 | |
|---|
| 1712 | | - root_dentry->d_fsdata = oe; |
|---|
| 1713 | | - |
|---|
| 1714 | 2057 | mntput(upperpath.mnt); |
|---|
| 1715 | | - if (upperpath.dentry) { |
|---|
| 1716 | | - ovl_dentry_set_upper_alias(root_dentry); |
|---|
| 1717 | | - if (ovl_is_impuredir(upperpath.dentry)) |
|---|
| 1718 | | - ovl_set_flag(OVL_IMPURE, d_inode(root_dentry)); |
|---|
| 1719 | | - } |
|---|
| 1720 | | - |
|---|
| 1721 | | - /* Root is always merge -> can have whiteouts */ |
|---|
| 1722 | | - ovl_set_flag(OVL_WHITEOUTS, d_inode(root_dentry)); |
|---|
| 1723 | | - ovl_dentry_set_flag(OVL_E_CONNECTED, root_dentry); |
|---|
| 1724 | | - ovl_set_upperdata(d_inode(root_dentry)); |
|---|
| 1725 | | - ovl_inode_init(d_inode(root_dentry), upperpath.dentry, |
|---|
| 1726 | | - ovl_dentry_lower(root_dentry), NULL); |
|---|
| 2058 | + kfree(splitlower); |
|---|
| 1727 | 2059 | |
|---|
| 1728 | 2060 | sb->s_root = root_dentry; |
|---|
| 1729 | 2061 | return 0; |
|---|
| .. | .. |
|---|
| 1732 | 2064 | ovl_entry_stack_free(oe); |
|---|
| 1733 | 2065 | kfree(oe); |
|---|
| 1734 | 2066 | out_err: |
|---|
| 2067 | + kfree(splitlower); |
|---|
| 1735 | 2068 | path_put(&upperpath); |
|---|
| 1736 | 2069 | ovl_free_fs(ofs); |
|---|
| 1737 | 2070 | out: |
|---|
| .. | .. |
|---|
| 1771 | 2104 | if (ovl_inode_cachep == NULL) |
|---|
| 1772 | 2105 | return -ENOMEM; |
|---|
| 1773 | 2106 | |
|---|
| 1774 | | - err = register_filesystem(&ovl_fs_type); |
|---|
| 1775 | | - if (err) |
|---|
| 1776 | | - kmem_cache_destroy(ovl_inode_cachep); |
|---|
| 2107 | + err = ovl_aio_request_cache_init(); |
|---|
| 2108 | + if (!err) { |
|---|
| 2109 | + err = register_filesystem(&ovl_fs_type); |
|---|
| 2110 | + if (!err) |
|---|
| 2111 | + return 0; |
|---|
| 2112 | + |
|---|
| 2113 | + ovl_aio_request_cache_destroy(); |
|---|
| 2114 | + } |
|---|
| 2115 | + kmem_cache_destroy(ovl_inode_cachep); |
|---|
| 1777 | 2116 | |
|---|
| 1778 | 2117 | return err; |
|---|
| 1779 | 2118 | } |
|---|
| .. | .. |
|---|
| 1788 | 2127 | */ |
|---|
| 1789 | 2128 | rcu_barrier(); |
|---|
| 1790 | 2129 | kmem_cache_destroy(ovl_inode_cachep); |
|---|
| 1791 | | - |
|---|
| 2130 | + ovl_aio_request_cache_destroy(); |
|---|
| 1792 | 2131 | } |
|---|
| 1793 | 2132 | |
|---|
| 1794 | 2133 | module_init(ovl_init); |
|---|