| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2011 Novell Inc. |
|---|
| 3 | 4 | * Copyright (C) 2016 Red Hat, 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 <linux/fs.h> |
|---|
| .. | .. |
|---|
| 33 | 30 | { |
|---|
| 34 | 31 | int res; |
|---|
| 35 | 32 | char *buf; |
|---|
| 33 | + struct ovl_fs *ofs = OVL_FS(d->sb); |
|---|
| 36 | 34 | |
|---|
| 37 | | - buf = ovl_get_redirect_xattr(dentry, prelen + strlen(post)); |
|---|
| 35 | + buf = ovl_get_redirect_xattr(ofs, dentry, prelen + strlen(post)); |
|---|
| 38 | 36 | if (IS_ERR_OR_NULL(buf)) |
|---|
| 39 | 37 | return PTR_ERR(buf); |
|---|
| 40 | 38 | |
|---|
| .. | .. |
|---|
| 87 | 85 | * Return -ENODATA for "origin unknown". |
|---|
| 88 | 86 | * Return <0 for an invalid file handle. |
|---|
| 89 | 87 | */ |
|---|
| 90 | | -int ovl_check_fh_len(struct ovl_fh *fh, int fh_len) |
|---|
| 88 | +int ovl_check_fb_len(struct ovl_fb *fb, int fb_len) |
|---|
| 91 | 89 | { |
|---|
| 92 | | - if (fh_len < sizeof(struct ovl_fh) || fh_len < fh->len) |
|---|
| 90 | + if (fb_len < sizeof(struct ovl_fb) || fb_len < fb->len) |
|---|
| 93 | 91 | return -EINVAL; |
|---|
| 94 | 92 | |
|---|
| 95 | | - if (fh->magic != OVL_FH_MAGIC) |
|---|
| 93 | + if (fb->magic != OVL_FH_MAGIC) |
|---|
| 96 | 94 | return -EINVAL; |
|---|
| 97 | 95 | |
|---|
| 98 | 96 | /* Treat larger version and unknown flags as "origin unknown" */ |
|---|
| 99 | | - if (fh->version > OVL_FH_VERSION || fh->flags & ~OVL_FH_FLAG_ALL) |
|---|
| 97 | + if (fb->version > OVL_FH_VERSION || fb->flags & ~OVL_FH_FLAG_ALL) |
|---|
| 100 | 98 | return -ENODATA; |
|---|
| 101 | 99 | |
|---|
| 102 | 100 | /* Treat endianness mismatch as "origin unknown" */ |
|---|
| 103 | | - if (!(fh->flags & OVL_FH_FLAG_ANY_ENDIAN) && |
|---|
| 104 | | - (fh->flags & OVL_FH_FLAG_BIG_ENDIAN) != OVL_FH_FLAG_CPU_ENDIAN) |
|---|
| 101 | + if (!(fb->flags & OVL_FH_FLAG_ANY_ENDIAN) && |
|---|
| 102 | + (fb->flags & OVL_FH_FLAG_BIG_ENDIAN) != OVL_FH_FLAG_CPU_ENDIAN) |
|---|
| 105 | 103 | return -ENODATA; |
|---|
| 106 | 104 | |
|---|
| 107 | 105 | return 0; |
|---|
| 108 | 106 | } |
|---|
| 109 | 107 | |
|---|
| 110 | | -static struct ovl_fh *ovl_get_fh(struct dentry *dentry, const char *name) |
|---|
| 108 | +static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *dentry, |
|---|
| 109 | + enum ovl_xattr ox) |
|---|
| 111 | 110 | { |
|---|
| 112 | 111 | ssize_t res; |
|---|
| 113 | 112 | int err; |
|---|
| 114 | 113 | struct ovl_fh *fh = NULL; |
|---|
| 115 | 114 | |
|---|
| 116 | | - res = ovl_vfs_getxattr(dentry, name, NULL, 0); |
|---|
| 115 | + res = ovl_do_getxattr(ofs, dentry, ox, NULL, 0); |
|---|
| 117 | 116 | if (res < 0) { |
|---|
| 118 | 117 | if (res == -ENODATA || res == -EOPNOTSUPP) |
|---|
| 119 | 118 | return NULL; |
|---|
| .. | .. |
|---|
| 123 | 122 | if (res == 0) |
|---|
| 124 | 123 | return NULL; |
|---|
| 125 | 124 | |
|---|
| 126 | | - fh = kzalloc(res, GFP_KERNEL); |
|---|
| 125 | + fh = kzalloc(res + OVL_FH_WIRE_OFFSET, GFP_KERNEL); |
|---|
| 127 | 126 | if (!fh) |
|---|
| 128 | 127 | return ERR_PTR(-ENOMEM); |
|---|
| 129 | 128 | |
|---|
| 130 | | - res = ovl_vfs_getxattr(dentry, name, fh, res); |
|---|
| 129 | + res = ovl_do_getxattr(ofs, dentry, ox, fh->buf, res); |
|---|
| 131 | 130 | if (res < 0) |
|---|
| 132 | 131 | goto fail; |
|---|
| 133 | 132 | |
|---|
| 134 | | - err = ovl_check_fh_len(fh, res); |
|---|
| 133 | + err = ovl_check_fb_len(&fh->fb, res); |
|---|
| 135 | 134 | if (err < 0) { |
|---|
| 136 | 135 | if (err == -ENODATA) |
|---|
| 137 | 136 | goto out; |
|---|
| .. | .. |
|---|
| 145 | 144 | return NULL; |
|---|
| 146 | 145 | |
|---|
| 147 | 146 | fail: |
|---|
| 148 | | - pr_warn_ratelimited("overlayfs: failed to get origin (%zi)\n", res); |
|---|
| 147 | + pr_warn_ratelimited("failed to get origin (%zi)\n", res); |
|---|
| 149 | 148 | goto out; |
|---|
| 150 | 149 | invalid: |
|---|
| 151 | | - pr_warn_ratelimited("overlayfs: invalid origin (%*phN)\n", |
|---|
| 152 | | - (int)res, fh); |
|---|
| 150 | + pr_warn_ratelimited("invalid origin (%*phN)\n", (int)res, fh); |
|---|
| 153 | 151 | goto out; |
|---|
| 154 | 152 | } |
|---|
| 155 | 153 | |
|---|
| .. | .. |
|---|
| 163 | 161 | * Make sure that the stored uuid matches the uuid of the lower |
|---|
| 164 | 162 | * layer where file handle will be decoded. |
|---|
| 165 | 163 | */ |
|---|
| 166 | | - if (!uuid_equal(&fh->uuid, &mnt->mnt_sb->s_uuid)) |
|---|
| 164 | + if (!uuid_equal(&fh->fb.uuid, &mnt->mnt_sb->s_uuid)) |
|---|
| 167 | 165 | return NULL; |
|---|
| 168 | 166 | |
|---|
| 169 | | - bytes = (fh->len - offsetof(struct ovl_fh, fid)); |
|---|
| 170 | | - real = exportfs_decode_fh(mnt, (struct fid *)fh->fid, |
|---|
| 171 | | - bytes >> 2, (int)fh->type, |
|---|
| 167 | + bytes = (fh->fb.len - offsetof(struct ovl_fb, fid)); |
|---|
| 168 | + real = exportfs_decode_fh(mnt, (struct fid *)fh->fb.fid, |
|---|
| 169 | + bytes >> 2, (int)fh->fb.type, |
|---|
| 172 | 170 | connected ? ovl_acceptable : NULL, mnt); |
|---|
| 173 | 171 | if (IS_ERR(real)) { |
|---|
| 174 | 172 | /* |
|---|
| .. | .. |
|---|
| 178 | 176 | * index entries correctly. |
|---|
| 179 | 177 | */ |
|---|
| 180 | 178 | if (real == ERR_PTR(-ESTALE) && |
|---|
| 181 | | - !(fh->flags & OVL_FH_FLAG_PATH_UPPER)) |
|---|
| 179 | + !(fh->fb.flags & OVL_FH_FLAG_PATH_UPPER)) |
|---|
| 182 | 180 | real = NULL; |
|---|
| 183 | 181 | return real; |
|---|
| 184 | 182 | } |
|---|
| .. | .. |
|---|
| 191 | 189 | return real; |
|---|
| 192 | 190 | } |
|---|
| 193 | 191 | |
|---|
| 194 | | -static bool ovl_is_opaquedir(struct dentry *dentry) |
|---|
| 192 | +static bool ovl_is_opaquedir(struct super_block *sb, struct dentry *dentry) |
|---|
| 195 | 193 | { |
|---|
| 196 | | - return ovl_check_dir_xattr(dentry, OVL_XATTR_OPAQUE); |
|---|
| 194 | + return ovl_check_dir_xattr(sb, dentry, OVL_XATTR_OPAQUE); |
|---|
| 195 | +} |
|---|
| 196 | + |
|---|
| 197 | +static struct dentry *ovl_lookup_positive_unlocked(const char *name, |
|---|
| 198 | + struct dentry *base, int len, |
|---|
| 199 | + bool drop_negative) |
|---|
| 200 | +{ |
|---|
| 201 | + struct dentry *ret = lookup_one_len_unlocked(name, base, len); |
|---|
| 202 | + |
|---|
| 203 | + if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) { |
|---|
| 204 | + if (drop_negative && ret->d_lockref.count == 1) { |
|---|
| 205 | + spin_lock(&ret->d_lock); |
|---|
| 206 | + /* Recheck condition under lock */ |
|---|
| 207 | + if (d_is_negative(ret) && ret->d_lockref.count == 1) |
|---|
| 208 | + __d_drop(ret); |
|---|
| 209 | + spin_unlock(&ret->d_lock); |
|---|
| 210 | + } |
|---|
| 211 | + dput(ret); |
|---|
| 212 | + ret = ERR_PTR(-ENOENT); |
|---|
| 213 | + } |
|---|
| 214 | + return ret; |
|---|
| 197 | 215 | } |
|---|
| 198 | 216 | |
|---|
| 199 | 217 | static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d, |
|---|
| 200 | 218 | const char *name, unsigned int namelen, |
|---|
| 201 | 219 | size_t prelen, const char *post, |
|---|
| 202 | | - struct dentry **ret) |
|---|
| 220 | + struct dentry **ret, bool drop_negative) |
|---|
| 203 | 221 | { |
|---|
| 204 | 222 | struct dentry *this; |
|---|
| 205 | 223 | int err; |
|---|
| 206 | 224 | bool last_element = !post[0]; |
|---|
| 207 | 225 | |
|---|
| 208 | | - this = lookup_one_len_unlocked(name, base, namelen); |
|---|
| 226 | + this = ovl_lookup_positive_unlocked(name, base, namelen, drop_negative); |
|---|
| 209 | 227 | if (IS_ERR(this)) { |
|---|
| 210 | 228 | err = PTR_ERR(this); |
|---|
| 211 | 229 | this = NULL; |
|---|
| .. | .. |
|---|
| 213 | 231 | goto out; |
|---|
| 214 | 232 | goto out_err; |
|---|
| 215 | 233 | } |
|---|
| 216 | | - if (!this->d_inode) |
|---|
| 217 | | - goto put_and_out; |
|---|
| 218 | 234 | |
|---|
| 219 | 235 | if (ovl_dentry_weird(this)) { |
|---|
| 220 | 236 | /* Don't support traversing automounts and other weirdness */ |
|---|
| .. | .. |
|---|
| 238 | 254 | d->stop = true; |
|---|
| 239 | 255 | goto put_and_out; |
|---|
| 240 | 256 | } |
|---|
| 241 | | - err = ovl_check_metacopy_xattr(this); |
|---|
| 257 | + err = ovl_check_metacopy_xattr(OVL_FS(d->sb), this); |
|---|
| 242 | 258 | if (err < 0) |
|---|
| 243 | 259 | goto out_err; |
|---|
| 244 | 260 | |
|---|
| .. | .. |
|---|
| 258 | 274 | if (d->last) |
|---|
| 259 | 275 | goto out; |
|---|
| 260 | 276 | |
|---|
| 261 | | - if (ovl_is_opaquedir(this)) { |
|---|
| 277 | + if (ovl_is_opaquedir(d->sb, this)) { |
|---|
| 262 | 278 | d->stop = true; |
|---|
| 263 | 279 | if (last_element) |
|---|
| 264 | 280 | d->opaque = true; |
|---|
| .. | .. |
|---|
| 283 | 299 | } |
|---|
| 284 | 300 | |
|---|
| 285 | 301 | static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d, |
|---|
| 286 | | - struct dentry **ret) |
|---|
| 302 | + struct dentry **ret, bool drop_negative) |
|---|
| 287 | 303 | { |
|---|
| 288 | 304 | /* Counting down from the end, since the prefix can change */ |
|---|
| 289 | 305 | size_t rem = d->name.len - 1; |
|---|
| .. | .. |
|---|
| 292 | 308 | |
|---|
| 293 | 309 | if (d->name.name[0] != '/') |
|---|
| 294 | 310 | return ovl_lookup_single(base, d, d->name.name, d->name.len, |
|---|
| 295 | | - 0, "", ret); |
|---|
| 311 | + 0, "", ret, drop_negative); |
|---|
| 296 | 312 | |
|---|
| 297 | 313 | while (!IS_ERR_OR_NULL(base) && d_can_lookup(base)) { |
|---|
| 298 | 314 | const char *s = d->name.name + d->name.len - rem; |
|---|
| .. | .. |
|---|
| 305 | 321 | return -EIO; |
|---|
| 306 | 322 | |
|---|
| 307 | 323 | err = ovl_lookup_single(base, d, s, thislen, |
|---|
| 308 | | - d->name.len - rem, next, &base); |
|---|
| 324 | + d->name.len - rem, next, &base, |
|---|
| 325 | + drop_negative); |
|---|
| 309 | 326 | dput(dentry); |
|---|
| 310 | 327 | if (err) |
|---|
| 311 | 328 | return err; |
|---|
| .. | .. |
|---|
| 329 | 346 | struct dentry *origin = NULL; |
|---|
| 330 | 347 | int i; |
|---|
| 331 | 348 | |
|---|
| 332 | | - for (i = 0; i < ofs->numlower; i++) { |
|---|
| 333 | | - origin = ovl_decode_real_fh(fh, ofs->lower_layers[i].mnt, |
|---|
| 349 | + for (i = 1; i < ofs->numlayer; i++) { |
|---|
| 350 | + /* |
|---|
| 351 | + * If lower fs uuid is not unique among lower fs we cannot match |
|---|
| 352 | + * fh->uuid to layer. |
|---|
| 353 | + */ |
|---|
| 354 | + if (ofs->layers[i].fsid && |
|---|
| 355 | + ofs->layers[i].fs->bad_uuid) |
|---|
| 356 | + continue; |
|---|
| 357 | + |
|---|
| 358 | + origin = ovl_decode_real_fh(fh, ofs->layers[i].mnt, |
|---|
| 334 | 359 | connected); |
|---|
| 335 | 360 | if (origin) |
|---|
| 336 | 361 | break; |
|---|
| .. | .. |
|---|
| 342 | 367 | return PTR_ERR(origin); |
|---|
| 343 | 368 | |
|---|
| 344 | 369 | if (upperdentry && !ovl_is_whiteout(upperdentry) && |
|---|
| 345 | | - ((d_inode(origin)->i_mode ^ d_inode(upperdentry)->i_mode) & S_IFMT)) |
|---|
| 370 | + inode_wrong_type(d_inode(upperdentry), d_inode(origin)->i_mode)) |
|---|
| 346 | 371 | goto invalid; |
|---|
| 347 | 372 | |
|---|
| 348 | 373 | if (!*stackp) |
|---|
| .. | .. |
|---|
| 353 | 378 | } |
|---|
| 354 | 379 | **stackp = (struct ovl_path){ |
|---|
| 355 | 380 | .dentry = origin, |
|---|
| 356 | | - .layer = &ofs->lower_layers[i] |
|---|
| 381 | + .layer = &ofs->layers[i] |
|---|
| 357 | 382 | }; |
|---|
| 358 | 383 | |
|---|
| 359 | 384 | return 0; |
|---|
| 360 | 385 | |
|---|
| 361 | 386 | invalid: |
|---|
| 362 | | - pr_warn_ratelimited("overlayfs: invalid origin (%pd2, ftype=%x, origin ftype=%x).\n", |
|---|
| 387 | + pr_warn_ratelimited("invalid origin (%pd2, ftype=%x, origin ftype=%x).\n", |
|---|
| 363 | 388 | upperdentry, d_inode(upperdentry)->i_mode & S_IFMT, |
|---|
| 364 | 389 | d_inode(origin)->i_mode & S_IFMT); |
|---|
| 365 | 390 | dput(origin); |
|---|
| .. | .. |
|---|
| 367 | 392 | } |
|---|
| 368 | 393 | |
|---|
| 369 | 394 | static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry, |
|---|
| 370 | | - struct ovl_path **stackp, unsigned int *ctrp) |
|---|
| 395 | + struct ovl_path **stackp) |
|---|
| 371 | 396 | { |
|---|
| 372 | | - struct ovl_fh *fh = ovl_get_fh(upperdentry, OVL_XATTR_ORIGIN); |
|---|
| 397 | + struct ovl_fh *fh = ovl_get_fh(ofs, upperdentry, OVL_XATTR_ORIGIN); |
|---|
| 373 | 398 | int err; |
|---|
| 374 | 399 | |
|---|
| 375 | 400 | if (IS_ERR_OR_NULL(fh)) |
|---|
| .. | .. |
|---|
| 384 | 409 | return err; |
|---|
| 385 | 410 | } |
|---|
| 386 | 411 | |
|---|
| 387 | | - if (WARN_ON(*ctrp)) |
|---|
| 388 | | - return -EIO; |
|---|
| 389 | | - |
|---|
| 390 | | - *ctrp = 1; |
|---|
| 391 | 412 | return 0; |
|---|
| 392 | 413 | } |
|---|
| 393 | 414 | |
|---|
| .. | .. |
|---|
| 395 | 416 | * Verify that @fh matches the file handle stored in xattr @name. |
|---|
| 396 | 417 | * Return 0 on match, -ESTALE on mismatch, < 0 on error. |
|---|
| 397 | 418 | */ |
|---|
| 398 | | -static int ovl_verify_fh(struct dentry *dentry, const char *name, |
|---|
| 399 | | - const struct ovl_fh *fh) |
|---|
| 419 | +static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry, |
|---|
| 420 | + enum ovl_xattr ox, const struct ovl_fh *fh) |
|---|
| 400 | 421 | { |
|---|
| 401 | | - struct ovl_fh *ofh = ovl_get_fh(dentry, name); |
|---|
| 422 | + struct ovl_fh *ofh = ovl_get_fh(ofs, dentry, ox); |
|---|
| 402 | 423 | int err = 0; |
|---|
| 403 | 424 | |
|---|
| 404 | 425 | if (!ofh) |
|---|
| .. | .. |
|---|
| 407 | 428 | if (IS_ERR(ofh)) |
|---|
| 408 | 429 | return PTR_ERR(ofh); |
|---|
| 409 | 430 | |
|---|
| 410 | | - if (fh->len != ofh->len || memcmp(fh, ofh, fh->len)) |
|---|
| 431 | + if (fh->fb.len != ofh->fb.len || memcmp(&fh->fb, &ofh->fb, fh->fb.len)) |
|---|
| 411 | 432 | err = -ESTALE; |
|---|
| 412 | 433 | |
|---|
| 413 | 434 | kfree(ofh); |
|---|
| .. | .. |
|---|
| 422 | 443 | * |
|---|
| 423 | 444 | * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error. |
|---|
| 424 | 445 | */ |
|---|
| 425 | | -int ovl_verify_set_fh(struct dentry *dentry, const char *name, |
|---|
| 426 | | - struct dentry *real, bool is_upper, bool set) |
|---|
| 446 | +int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry, |
|---|
| 447 | + enum ovl_xattr ox, struct dentry *real, bool is_upper, |
|---|
| 448 | + bool set) |
|---|
| 427 | 449 | { |
|---|
| 428 | 450 | struct inode *inode; |
|---|
| 429 | 451 | struct ovl_fh *fh; |
|---|
| .. | .. |
|---|
| 436 | 458 | goto fail; |
|---|
| 437 | 459 | } |
|---|
| 438 | 460 | |
|---|
| 439 | | - err = ovl_verify_fh(dentry, name, fh); |
|---|
| 461 | + err = ovl_verify_fh(ofs, dentry, ox, fh); |
|---|
| 440 | 462 | if (set && err == -ENODATA) |
|---|
| 441 | | - err = ovl_do_setxattr(dentry, name, fh, fh->len, 0); |
|---|
| 463 | + err = ovl_do_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len); |
|---|
| 442 | 464 | if (err) |
|---|
| 443 | 465 | goto fail; |
|---|
| 444 | 466 | |
|---|
| .. | .. |
|---|
| 448 | 470 | |
|---|
| 449 | 471 | fail: |
|---|
| 450 | 472 | inode = d_inode(real); |
|---|
| 451 | | - pr_warn_ratelimited("overlayfs: failed to verify %s (%pd2, ino=%lu, err=%i)\n", |
|---|
| 473 | + pr_warn_ratelimited("failed to verify %s (%pd2, ino=%lu, err=%i)\n", |
|---|
| 452 | 474 | is_upper ? "upper" : "origin", real, |
|---|
| 453 | 475 | inode ? inode->i_ino : 0, err); |
|---|
| 454 | 476 | goto out; |
|---|
| .. | .. |
|---|
| 463 | 485 | if (!d_is_dir(index)) |
|---|
| 464 | 486 | return dget(index); |
|---|
| 465 | 487 | |
|---|
| 466 | | - fh = ovl_get_fh(index, OVL_XATTR_UPPER); |
|---|
| 488 | + fh = ovl_get_fh(ofs, index, OVL_XATTR_UPPER); |
|---|
| 467 | 489 | if (IS_ERR_OR_NULL(fh)) |
|---|
| 468 | 490 | return ERR_CAST(fh); |
|---|
| 469 | 491 | |
|---|
| 470 | | - upper = ovl_decode_real_fh(fh, ofs->upper_mnt, true); |
|---|
| 492 | + upper = ovl_decode_real_fh(fh, ovl_upper_mnt(ofs), true); |
|---|
| 471 | 493 | kfree(fh); |
|---|
| 472 | 494 | |
|---|
| 473 | 495 | if (IS_ERR_OR_NULL(upper)) |
|---|
| 474 | 496 | return upper ?: ERR_PTR(-ESTALE); |
|---|
| 475 | 497 | |
|---|
| 476 | 498 | if (!d_is_dir(upper)) { |
|---|
| 477 | | - pr_warn_ratelimited("overlayfs: invalid index upper (%pd2, upper=%pd2).\n", |
|---|
| 499 | + pr_warn_ratelimited("invalid index upper (%pd2, upper=%pd2).\n", |
|---|
| 478 | 500 | index, upper); |
|---|
| 479 | 501 | dput(upper); |
|---|
| 480 | 502 | return ERR_PTR(-EIO); |
|---|
| 481 | 503 | } |
|---|
| 482 | 504 | |
|---|
| 483 | 505 | return upper; |
|---|
| 484 | | -} |
|---|
| 485 | | - |
|---|
| 486 | | -/* Is this a leftover from create/whiteout of directory index entry? */ |
|---|
| 487 | | -static bool ovl_is_temp_index(struct dentry *index) |
|---|
| 488 | | -{ |
|---|
| 489 | | - return index->d_name.name[0] == '#'; |
|---|
| 490 | 506 | } |
|---|
| 491 | 507 | |
|---|
| 492 | 508 | /* |
|---|
| .. | .. |
|---|
| 506 | 522 | if (!d_inode(index)) |
|---|
| 507 | 523 | return 0; |
|---|
| 508 | 524 | |
|---|
| 509 | | - /* Cleanup leftover from index create/cleanup attempt */ |
|---|
| 510 | | - err = -ESTALE; |
|---|
| 511 | | - if (ovl_is_temp_index(index)) |
|---|
| 512 | | - goto fail; |
|---|
| 513 | | - |
|---|
| 514 | 525 | err = -EINVAL; |
|---|
| 515 | | - if (index->d_name.len < sizeof(struct ovl_fh)*2) |
|---|
| 526 | + if (index->d_name.len < sizeof(struct ovl_fb)*2) |
|---|
| 516 | 527 | goto fail; |
|---|
| 517 | 528 | |
|---|
| 518 | 529 | err = -ENOMEM; |
|---|
| 519 | 530 | len = index->d_name.len / 2; |
|---|
| 520 | | - fh = kzalloc(len, GFP_KERNEL); |
|---|
| 531 | + fh = kzalloc(len + OVL_FH_WIRE_OFFSET, GFP_KERNEL); |
|---|
| 521 | 532 | if (!fh) |
|---|
| 522 | 533 | goto fail; |
|---|
| 523 | 534 | |
|---|
| 524 | 535 | err = -EINVAL; |
|---|
| 525 | | - if (hex2bin((u8 *)fh, index->d_name.name, len)) |
|---|
| 536 | + if (hex2bin(fh->buf, index->d_name.name, len)) |
|---|
| 526 | 537 | goto fail; |
|---|
| 527 | 538 | |
|---|
| 528 | | - err = ovl_check_fh_len(fh, len); |
|---|
| 539 | + err = ovl_check_fb_len(&fh->fb, len); |
|---|
| 529 | 540 | if (err) |
|---|
| 530 | 541 | goto fail; |
|---|
| 531 | 542 | |
|---|
| .. | .. |
|---|
| 567 | 578 | goto fail; |
|---|
| 568 | 579 | } |
|---|
| 569 | 580 | |
|---|
| 570 | | - err = ovl_verify_fh(upper, OVL_XATTR_ORIGIN, fh); |
|---|
| 581 | + err = ovl_verify_fh(ofs, upper, OVL_XATTR_ORIGIN, fh); |
|---|
| 571 | 582 | dput(upper); |
|---|
| 572 | 583 | if (err) |
|---|
| 573 | 584 | goto fail; |
|---|
| .. | .. |
|---|
| 578 | 589 | if (err) |
|---|
| 579 | 590 | goto fail; |
|---|
| 580 | 591 | |
|---|
| 581 | | - if (ovl_get_nlink(origin.dentry, index, 0) == 0) |
|---|
| 592 | + if (ovl_get_nlink(ofs, origin.dentry, index, 0) == 0) |
|---|
| 582 | 593 | goto orphan; |
|---|
| 583 | 594 | } |
|---|
| 584 | 595 | |
|---|
| .. | .. |
|---|
| 588 | 599 | return err; |
|---|
| 589 | 600 | |
|---|
| 590 | 601 | fail: |
|---|
| 591 | | - pr_warn_ratelimited("overlayfs: failed to verify index (%pd2, ftype=%x, err=%i)\n", |
|---|
| 602 | + pr_warn_ratelimited("failed to verify index (%pd2, ftype=%x, err=%i)\n", |
|---|
| 592 | 603 | index, d_inode(index)->i_mode & S_IFMT, err); |
|---|
| 593 | 604 | goto out; |
|---|
| 594 | 605 | |
|---|
| 595 | 606 | orphan: |
|---|
| 596 | | - pr_warn_ratelimited("overlayfs: orphan index entry (%pd2, ftype=%x, nlink=%u)\n", |
|---|
| 607 | + pr_warn_ratelimited("orphan index entry (%pd2, ftype=%x, nlink=%u)\n", |
|---|
| 597 | 608 | index, d_inode(index)->i_mode & S_IFMT, |
|---|
| 598 | 609 | d_inode(index)->i_nlink); |
|---|
| 599 | 610 | err = -ENOENT; |
|---|
| .. | .. |
|---|
| 604 | 615 | { |
|---|
| 605 | 616 | char *n, *s; |
|---|
| 606 | 617 | |
|---|
| 607 | | - n = kcalloc(fh->len, 2, GFP_KERNEL); |
|---|
| 618 | + n = kcalloc(fh->fb.len, 2, GFP_KERNEL); |
|---|
| 608 | 619 | if (!n) |
|---|
| 609 | 620 | return -ENOMEM; |
|---|
| 610 | 621 | |
|---|
| 611 | | - s = bin2hex(n, fh, fh->len); |
|---|
| 622 | + s = bin2hex(n, fh->buf, fh->fb.len); |
|---|
| 612 | 623 | *name = (struct qstr) QSTR_INIT(n, s - n); |
|---|
| 613 | 624 | |
|---|
| 614 | 625 | return 0; |
|---|
| .. | .. |
|---|
| 656 | 667 | if (err) |
|---|
| 657 | 668 | return ERR_PTR(err); |
|---|
| 658 | 669 | |
|---|
| 659 | | - index = lookup_one_len_unlocked(name.name, ofs->indexdir, name.len); |
|---|
| 670 | + index = lookup_positive_unlocked(name.name, ofs->indexdir, name.len); |
|---|
| 660 | 671 | kfree(name.name); |
|---|
| 661 | 672 | if (IS_ERR(index)) { |
|---|
| 662 | 673 | if (PTR_ERR(index) == -ENOENT) |
|---|
| .. | .. |
|---|
| 664 | 675 | return index; |
|---|
| 665 | 676 | } |
|---|
| 666 | 677 | |
|---|
| 667 | | - if (d_is_negative(index)) |
|---|
| 668 | | - err = 0; |
|---|
| 669 | | - else if (ovl_is_whiteout(index)) |
|---|
| 678 | + if (ovl_is_whiteout(index)) |
|---|
| 670 | 679 | err = -ESTALE; |
|---|
| 671 | 680 | else if (ovl_dentry_weird(index)) |
|---|
| 672 | 681 | err = -EIO; |
|---|
| .. | .. |
|---|
| 690 | 699 | if (err) |
|---|
| 691 | 700 | return ERR_PTR(err); |
|---|
| 692 | 701 | |
|---|
| 693 | | - index = lookup_one_len_unlocked(name.name, ofs->indexdir, name.len); |
|---|
| 702 | + index = lookup_positive_unlocked(name.name, ofs->indexdir, name.len); |
|---|
| 694 | 703 | if (IS_ERR(index)) { |
|---|
| 695 | 704 | err = PTR_ERR(index); |
|---|
| 696 | 705 | if (err == -ENOENT) { |
|---|
| 697 | 706 | index = NULL; |
|---|
| 698 | 707 | goto out; |
|---|
| 699 | 708 | } |
|---|
| 700 | | - pr_warn_ratelimited("overlayfs: failed inode index lookup (ino=%lu, key=%.*s, err=%i);\n" |
|---|
| 709 | + pr_warn_ratelimited("failed inode index lookup (ino=%lu, key=%.*s, err=%i);\n" |
|---|
| 701 | 710 | "overlayfs: mount with '-o index=off' to disable inodes index.\n", |
|---|
| 702 | 711 | d_inode(origin)->i_ino, name.len, name.name, |
|---|
| 703 | 712 | err); |
|---|
| .. | .. |
|---|
| 705 | 714 | } |
|---|
| 706 | 715 | |
|---|
| 707 | 716 | inode = d_inode(index); |
|---|
| 708 | | - if (d_is_negative(index)) { |
|---|
| 709 | | - goto out_dput; |
|---|
| 710 | | - } else if (ovl_is_whiteout(index) && !verify) { |
|---|
| 717 | + if (ovl_is_whiteout(index) && !verify) { |
|---|
| 711 | 718 | /* |
|---|
| 712 | 719 | * When index lookup is called with !verify for decoding an |
|---|
| 713 | 720 | * overlay file handle, a whiteout index implies that decode |
|---|
| .. | .. |
|---|
| 718 | 725 | index = ERR_PTR(-ESTALE); |
|---|
| 719 | 726 | goto out; |
|---|
| 720 | 727 | } else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) || |
|---|
| 721 | | - ((inode->i_mode ^ d_inode(origin)->i_mode) & S_IFMT)) { |
|---|
| 728 | + inode_wrong_type(inode, d_inode(origin)->i_mode)) { |
|---|
| 722 | 729 | /* |
|---|
| 723 | 730 | * Index should always be of the same file type as origin |
|---|
| 724 | 731 | * except for the case of a whiteout index. A whiteout |
|---|
| .. | .. |
|---|
| 726 | 733 | * unlinked, which means that finding a lower origin on lookup |
|---|
| 727 | 734 | * whose index is a whiteout should be treated as an error. |
|---|
| 728 | 735 | */ |
|---|
| 729 | | - pr_warn_ratelimited("overlayfs: bad index found (index=%pd2, ftype=%x, origin ftype=%x).\n", |
|---|
| 736 | + pr_warn_ratelimited("bad index found (index=%pd2, ftype=%x, origin ftype=%x).\n", |
|---|
| 730 | 737 | index, d_inode(index)->i_mode & S_IFMT, |
|---|
| 731 | 738 | d_inode(origin)->i_mode & S_IFMT); |
|---|
| 732 | 739 | goto fail; |
|---|
| 733 | 740 | } else if (is_dir && verify) { |
|---|
| 734 | 741 | if (!upper) { |
|---|
| 735 | | - pr_warn_ratelimited("overlayfs: suspected uncovered redirected dir found (origin=%pd2, index=%pd2).\n", |
|---|
| 742 | + pr_warn_ratelimited("suspected uncovered redirected dir found (origin=%pd2, index=%pd2).\n", |
|---|
| 736 | 743 | origin, index); |
|---|
| 737 | 744 | goto fail; |
|---|
| 738 | 745 | } |
|---|
| 739 | 746 | |
|---|
| 740 | 747 | /* Verify that dir index 'upper' xattr points to upper dir */ |
|---|
| 741 | | - err = ovl_verify_upper(index, upper, false); |
|---|
| 748 | + err = ovl_verify_upper(ofs, index, upper, false); |
|---|
| 742 | 749 | if (err) { |
|---|
| 743 | 750 | if (err == -ESTALE) { |
|---|
| 744 | | - pr_warn_ratelimited("overlayfs: suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n", |
|---|
| 751 | + pr_warn_ratelimited("suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n", |
|---|
| 745 | 752 | upper, origin, index); |
|---|
| 746 | 753 | } |
|---|
| 747 | 754 | goto fail; |
|---|
| .. | .. |
|---|
| 787 | 794 | } |
|---|
| 788 | 795 | |
|---|
| 789 | 796 | /* Fix missing 'origin' xattr */ |
|---|
| 790 | | -static int ovl_fix_origin(struct dentry *dentry, struct dentry *lower, |
|---|
| 791 | | - struct dentry *upper) |
|---|
| 797 | +static int ovl_fix_origin(struct ovl_fs *ofs, struct dentry *dentry, |
|---|
| 798 | + struct dentry *lower, struct dentry *upper) |
|---|
| 792 | 799 | { |
|---|
| 793 | 800 | int err; |
|---|
| 794 | 801 | |
|---|
| 795 | | - if (ovl_check_origin_xattr(upper)) |
|---|
| 802 | + if (ovl_check_origin_xattr(ofs, upper)) |
|---|
| 796 | 803 | return 0; |
|---|
| 797 | 804 | |
|---|
| 798 | 805 | err = ovl_want_write(dentry); |
|---|
| .. | .. |
|---|
| 826 | 833 | struct dentry *this; |
|---|
| 827 | 834 | unsigned int i; |
|---|
| 828 | 835 | int err; |
|---|
| 829 | | - bool metacopy = false; |
|---|
| 836 | + bool uppermetacopy = false; |
|---|
| 830 | 837 | struct ovl_lookup_data d = { |
|---|
| 831 | 838 | .sb = dentry->d_sb, |
|---|
| 832 | 839 | .name = dentry->d_name, |
|---|
| .. | .. |
|---|
| 844 | 851 | old_cred = ovl_override_creds(dentry->d_sb); |
|---|
| 845 | 852 | upperdir = ovl_dentry_upper(dentry->d_parent); |
|---|
| 846 | 853 | if (upperdir) { |
|---|
| 847 | | - err = ovl_lookup_layer(upperdir, &d, &upperdentry); |
|---|
| 854 | + err = ovl_lookup_layer(upperdir, &d, &upperdentry, true); |
|---|
| 848 | 855 | if (err) |
|---|
| 849 | 856 | goto out; |
|---|
| 850 | 857 | |
|---|
| 851 | | - if (upperdentry && unlikely(ovl_dentry_remote(upperdentry))) { |
|---|
| 858 | + if (upperdentry && upperdentry->d_flags & DCACHE_OP_REAL) { |
|---|
| 852 | 859 | dput(upperdentry); |
|---|
| 853 | 860 | err = -EREMOTE; |
|---|
| 854 | 861 | goto out; |
|---|
| 855 | 862 | } |
|---|
| 856 | 863 | if (upperdentry && !d.is_dir) { |
|---|
| 857 | | - unsigned int origin_ctr = 0; |
|---|
| 858 | | - |
|---|
| 859 | 864 | /* |
|---|
| 860 | 865 | * Lookup copy up origin by decoding origin file handle. |
|---|
| 861 | 866 | * We may get a disconnected dentry, which is fine, |
|---|
| .. | .. |
|---|
| 866 | 871 | * number - it's the same as if we held a reference |
|---|
| 867 | 872 | * to a dentry in lower layer that was moved under us. |
|---|
| 868 | 873 | */ |
|---|
| 869 | | - err = ovl_check_origin(ofs, upperdentry, &origin_path, |
|---|
| 870 | | - &origin_ctr); |
|---|
| 874 | + err = ovl_check_origin(ofs, upperdentry, &origin_path); |
|---|
| 871 | 875 | if (err) |
|---|
| 872 | 876 | goto out_put_upper; |
|---|
| 873 | 877 | |
|---|
| 874 | 878 | if (d.metacopy) |
|---|
| 875 | | - metacopy = true; |
|---|
| 879 | + uppermetacopy = true; |
|---|
| 876 | 880 | } |
|---|
| 877 | 881 | |
|---|
| 878 | 882 | if (d.redirect) { |
|---|
| .. | .. |
|---|
| 888 | 892 | |
|---|
| 889 | 893 | if (!d.stop && poe->numlower) { |
|---|
| 890 | 894 | err = -ENOMEM; |
|---|
| 891 | | - stack = kcalloc(ofs->numlower, sizeof(struct ovl_path), |
|---|
| 895 | + stack = kcalloc(ofs->numlayer - 1, sizeof(struct ovl_path), |
|---|
| 892 | 896 | GFP_KERNEL); |
|---|
| 893 | 897 | if (!stack) |
|---|
| 894 | 898 | goto out_put_upper; |
|---|
| .. | .. |
|---|
| 902 | 906 | else |
|---|
| 903 | 907 | d.last = lower.layer->idx == roe->numlower; |
|---|
| 904 | 908 | |
|---|
| 905 | | - err = ovl_lookup_layer(lower.dentry, &d, &this); |
|---|
| 909 | + err = ovl_lookup_layer(lower.dentry, &d, &this, false); |
|---|
| 906 | 910 | if (err) |
|---|
| 907 | 911 | goto out_put; |
|---|
| 908 | 912 | |
|---|
| 909 | 913 | if (!this) |
|---|
| 910 | 914 | continue; |
|---|
| 911 | 915 | |
|---|
| 916 | + if ((uppermetacopy || d.metacopy) && !ofs->config.metacopy) { |
|---|
| 917 | + dput(this); |
|---|
| 918 | + err = -EPERM; |
|---|
| 919 | + pr_warn_ratelimited("refusing to follow metacopy origin for (%pd2)\n", dentry); |
|---|
| 920 | + goto out_put; |
|---|
| 921 | + } |
|---|
| 922 | + |
|---|
| 912 | 923 | /* |
|---|
| 913 | 924 | * If no origin fh is stored in upper of a merge dir, store fh |
|---|
| 914 | 925 | * of lower dir and set upper parent "impure". |
|---|
| 915 | 926 | */ |
|---|
| 916 | 927 | if (upperdentry && !ctr && !ofs->noxattr && d.is_dir) { |
|---|
| 917 | | - err = ovl_fix_origin(dentry, this, upperdentry); |
|---|
| 928 | + err = ovl_fix_origin(ofs, dentry, this, upperdentry); |
|---|
| 918 | 929 | if (err) { |
|---|
| 919 | 930 | dput(this); |
|---|
| 920 | 931 | goto out_put; |
|---|
| .. | .. |
|---|
| 933 | 944 | if (upperdentry && !ctr && |
|---|
| 934 | 945 | ((d.is_dir && ovl_verify_lower(dentry->d_sb)) || |
|---|
| 935 | 946 | (!d.is_dir && ofs->config.index && origin_path))) { |
|---|
| 936 | | - err = ovl_verify_origin(upperdentry, this, false); |
|---|
| 947 | + err = ovl_verify_origin(ofs, upperdentry, this, false); |
|---|
| 937 | 948 | if (err) { |
|---|
| 938 | 949 | dput(this); |
|---|
| 939 | 950 | if (d.is_dir) |
|---|
| .. | .. |
|---|
| 943 | 954 | origin = this; |
|---|
| 944 | 955 | } |
|---|
| 945 | 956 | |
|---|
| 946 | | - if (d.metacopy) |
|---|
| 947 | | - metacopy = true; |
|---|
| 948 | | - /* |
|---|
| 949 | | - * Do not store intermediate metacopy dentries in chain, |
|---|
| 950 | | - * except top most lower metacopy dentry |
|---|
| 951 | | - */ |
|---|
| 952 | 957 | if (d.metacopy && ctr) { |
|---|
| 958 | + /* |
|---|
| 959 | + * Do not store intermediate metacopy dentries in |
|---|
| 960 | + * lower chain, except top most lower metacopy dentry. |
|---|
| 961 | + * Continue the loop so that if there is an absolute |
|---|
| 962 | + * redirect on this dentry, poe can be reset to roe. |
|---|
| 963 | + */ |
|---|
| 953 | 964 | dput(this); |
|---|
| 954 | | - continue; |
|---|
| 965 | + this = NULL; |
|---|
| 966 | + } else { |
|---|
| 967 | + stack[ctr].dentry = this; |
|---|
| 968 | + stack[ctr].layer = lower.layer; |
|---|
| 969 | + ctr++; |
|---|
| 955 | 970 | } |
|---|
| 956 | | - |
|---|
| 957 | | - stack[ctr].dentry = this; |
|---|
| 958 | | - stack[ctr].layer = lower.layer; |
|---|
| 959 | | - ctr++; |
|---|
| 960 | 971 | |
|---|
| 961 | 972 | /* |
|---|
| 962 | 973 | * Following redirects can have security consequences: it's like |
|---|
| .. | .. |
|---|
| 970 | 981 | */ |
|---|
| 971 | 982 | err = -EPERM; |
|---|
| 972 | 983 | if (d.redirect && !ofs->config.redirect_follow) { |
|---|
| 973 | | - pr_warn_ratelimited("overlayfs: refusing to follow redirect for (%pd2)\n", |
|---|
| 984 | + pr_warn_ratelimited("refusing to follow redirect for (%pd2)\n", |
|---|
| 974 | 985 | dentry); |
|---|
| 975 | 986 | goto out_put; |
|---|
| 976 | 987 | } |
|---|
| .. | .. |
|---|
| 985 | 996 | } |
|---|
| 986 | 997 | } |
|---|
| 987 | 998 | |
|---|
| 988 | | - if (metacopy) { |
|---|
| 989 | | - /* |
|---|
| 990 | | - * Found a metacopy dentry but did not find corresponding |
|---|
| 991 | | - * data dentry |
|---|
| 992 | | - */ |
|---|
| 993 | | - if (d.metacopy) { |
|---|
| 994 | | - err = -EIO; |
|---|
| 995 | | - goto out_put; |
|---|
| 996 | | - } |
|---|
| 997 | | - |
|---|
| 998 | | - err = -EPERM; |
|---|
| 999 | | - if (!ofs->config.metacopy) { |
|---|
| 1000 | | - pr_warn_ratelimited("overlay: refusing to follow metacopy origin for (%pd2)\n", |
|---|
| 1001 | | - dentry); |
|---|
| 1002 | | - goto out_put; |
|---|
| 1003 | | - } |
|---|
| 999 | + /* |
|---|
| 1000 | + * For regular non-metacopy upper dentries, there is no lower |
|---|
| 1001 | + * path based lookup, hence ctr will be zero. If a dentry is found |
|---|
| 1002 | + * using ORIGIN xattr on upper, install it in stack. |
|---|
| 1003 | + * |
|---|
| 1004 | + * For metacopy dentry, path based lookup will find lower dentries. |
|---|
| 1005 | + * Just make sure a corresponding data dentry has been found. |
|---|
| 1006 | + */ |
|---|
| 1007 | + if (d.metacopy || (uppermetacopy && !ctr)) { |
|---|
| 1008 | + err = -EIO; |
|---|
| 1009 | + goto out_put; |
|---|
| 1004 | 1010 | } else if (!d.is_dir && upperdentry && !ctr && origin_path) { |
|---|
| 1005 | 1011 | if (WARN_ON(stack != NULL)) { |
|---|
| 1006 | 1012 | err = -EIO; |
|---|
| .. | .. |
|---|
| 1008 | 1014 | } |
|---|
| 1009 | 1015 | stack = origin_path; |
|---|
| 1010 | 1016 | ctr = 1; |
|---|
| 1017 | + origin = origin_path->dentry; |
|---|
| 1011 | 1018 | origin_path = NULL; |
|---|
| 1012 | 1019 | } |
|---|
| 1013 | 1020 | |
|---|
| 1014 | 1021 | /* |
|---|
| 1015 | | - * Lookup index by lower inode and verify it matches upper inode. |
|---|
| 1016 | | - * We only trust dir index if we verified that lower dir matches |
|---|
| 1017 | | - * origin, otherwise dir index entries may be inconsistent and we |
|---|
| 1018 | | - * ignore them. |
|---|
| 1022 | + * Always lookup index if there is no-upperdentry. |
|---|
| 1019 | 1023 | * |
|---|
| 1020 | | - * For non-dir upper metacopy dentry, we already set "origin" if we |
|---|
| 1021 | | - * verified that lower matched upper origin. If upper origin was |
|---|
| 1022 | | - * not present (because lower layer did not support fh encode/decode), |
|---|
| 1023 | | - * or indexing is not enabled, do not set "origin" and skip looking up |
|---|
| 1024 | | - * index. This case should be handled in same way as a non-dir upper |
|---|
| 1025 | | - * without ORIGIN is handled. |
|---|
| 1024 | + * For the case of upperdentry, we have set origin by now if it |
|---|
| 1025 | + * needed to be set. There are basically three cases. |
|---|
| 1026 | 1026 | * |
|---|
| 1027 | | - * Always lookup index of non-dir non-metacopy and non-upper. |
|---|
| 1027 | + * For directories, lookup index by lower inode and verify it matches |
|---|
| 1028 | + * upper inode. We only trust dir index if we verified that lower dir |
|---|
| 1029 | + * matches origin, otherwise dir index entries may be inconsistent |
|---|
| 1030 | + * and we ignore them. |
|---|
| 1031 | + * |
|---|
| 1032 | + * For regular upper, we already set origin if upper had ORIGIN |
|---|
| 1033 | + * xattr. There is no verification though as there is no path |
|---|
| 1034 | + * based dentry lookup in lower in this case. |
|---|
| 1035 | + * |
|---|
| 1036 | + * For metacopy upper, we set a verified origin already if index |
|---|
| 1037 | + * is enabled and if upper had an ORIGIN xattr. |
|---|
| 1038 | + * |
|---|
| 1028 | 1039 | */ |
|---|
| 1029 | | - if (ctr && (!upperdentry || (!d.is_dir && !metacopy))) |
|---|
| 1040 | + if (!upperdentry && ctr) |
|---|
| 1030 | 1041 | origin = stack[0].dentry; |
|---|
| 1031 | 1042 | |
|---|
| 1032 | 1043 | if (origin && ovl_indexdir(dentry->d_sb) && |
|---|
| .. | .. |
|---|
| 1054 | 1065 | ovl_dentry_set_upper_alias(dentry); |
|---|
| 1055 | 1066 | else if (index) { |
|---|
| 1056 | 1067 | upperdentry = dget(index); |
|---|
| 1057 | | - upperredirect = ovl_get_redirect_xattr(upperdentry, 0); |
|---|
| 1068 | + upperredirect = ovl_get_redirect_xattr(ofs, upperdentry, 0); |
|---|
| 1058 | 1069 | if (IS_ERR(upperredirect)) { |
|---|
| 1059 | 1070 | err = PTR_ERR(upperredirect); |
|---|
| 1060 | 1071 | upperredirect = NULL; |
|---|
| 1061 | 1072 | goto out_free_oe; |
|---|
| 1062 | 1073 | } |
|---|
| 1074 | + err = ovl_check_metacopy_xattr(ofs, upperdentry); |
|---|
| 1075 | + if (err < 0) |
|---|
| 1076 | + goto out_free_oe; |
|---|
| 1077 | + uppermetacopy = err; |
|---|
| 1063 | 1078 | } |
|---|
| 1064 | 1079 | |
|---|
| 1065 | 1080 | if (upperdentry || ctr) { |
|---|
| .. | .. |
|---|
| 1077 | 1092 | err = PTR_ERR(inode); |
|---|
| 1078 | 1093 | if (IS_ERR(inode)) |
|---|
| 1079 | 1094 | goto out_free_oe; |
|---|
| 1095 | + if (upperdentry && !uppermetacopy) |
|---|
| 1096 | + ovl_set_flag(OVL_UPPERDATA, inode); |
|---|
| 1080 | 1097 | } |
|---|
| 1081 | 1098 | |
|---|
| 1082 | | - ovl_revert_creds(old_cred); |
|---|
| 1099 | + ovl_dentry_init_reval(dentry, upperdentry); |
|---|
| 1100 | + |
|---|
| 1101 | + ovl_revert_creds(dentry->d_sb, old_cred); |
|---|
| 1083 | 1102 | if (origin_path) { |
|---|
| 1084 | 1103 | dput(origin_path->dentry); |
|---|
| 1085 | 1104 | kfree(origin_path); |
|---|
| .. | .. |
|---|
| 1106 | 1125 | kfree(upperredirect); |
|---|
| 1107 | 1126 | out: |
|---|
| 1108 | 1127 | kfree(d.redirect); |
|---|
| 1109 | | - ovl_revert_creds(old_cred); |
|---|
| 1128 | + ovl_revert_creds(dentry->d_sb, old_cred); |
|---|
| 1110 | 1129 | return ERR_PTR(err); |
|---|
| 1111 | 1130 | } |
|---|
| 1112 | 1131 | |
|---|
| .. | .. |
|---|
| 1136 | 1155 | struct dentry *this; |
|---|
| 1137 | 1156 | struct dentry *lowerdir = poe->lowerstack[i].dentry; |
|---|
| 1138 | 1157 | |
|---|
| 1139 | | - this = lookup_one_len_unlocked(name->name, lowerdir, |
|---|
| 1158 | + this = lookup_positive_unlocked(name->name, lowerdir, |
|---|
| 1140 | 1159 | name->len); |
|---|
| 1141 | 1160 | if (IS_ERR(this)) { |
|---|
| 1142 | 1161 | switch (PTR_ERR(this)) { |
|---|
| .. | .. |
|---|
| 1153 | 1172 | break; |
|---|
| 1154 | 1173 | } |
|---|
| 1155 | 1174 | } else { |
|---|
| 1156 | | - if (this->d_inode) { |
|---|
| 1157 | | - positive = !ovl_is_whiteout(this); |
|---|
| 1158 | | - done = true; |
|---|
| 1159 | | - } |
|---|
| 1175 | + positive = !ovl_is_whiteout(this); |
|---|
| 1176 | + done = true; |
|---|
| 1160 | 1177 | dput(this); |
|---|
| 1161 | 1178 | } |
|---|
| 1162 | 1179 | } |
|---|
| 1163 | | - ovl_revert_creds(old_cred); |
|---|
| 1180 | + ovl_revert_creds(dentry->d_sb, old_cred); |
|---|
| 1164 | 1181 | |
|---|
| 1165 | 1182 | return positive; |
|---|
| 1166 | 1183 | } |
|---|