Lines Matching +full:real +full:- +full:time

1 // SPDX-License-Identifier: GPL-2.0-only
7 * Copyright (C) 2017-2018 CTERA Networks. All Rights Reserved.
36 * Before encoding a non-upper directory file handle from real layer N, we need
37 * to check if it will be possible to reconnect an overlay dentry from the real
53 * To avoid this problem on decode time, we need to copy up an ancestor of
54 * /a/b/c, which is "layer 2 connectable", on encode time. That ancestor is
56 * and when the time comes to decode the file handle from lower dentry /a/b/c,
77 if (dentry == dentry->d_sb->s_root) in ovl_connectable_layer()
89 return ovl_lowerstack(oe)->layer->idx; in ovl_connectable_layer()
107 if (WARN_ON(dentry == dentry->d_sb->s_root) || in ovl_connect_layer()
109 return -EIO; in ovl_connect_layer()
111 origin_layer = ovl_lowerstack(oe)->layer->idx; in ovl_connect_layer()
120 err = -EIO; in ovl_connect_layer()
154 * encoding also after copy up. If non-pure upper is not indexed, then it was
157 * file handle. Overlay root dentry is a private case of non-indexed upper.
163 * --------------------------------
165 * Non-indexed upper | U
167 * Non-upper | L (*)
172 * (*) Decoding a connected overlay dir from real lower dentry is not always
173 * possible when there are redirects in lower layers and non-indexed merge dirs.
175 * of a decodable file handle for non-upper dir.
181 struct ovl_fs *ofs = OVL_FS(dentry->d_sb); in ovl_check_encode_origin()
182 bool decodable = ofs->config.nfs_export; in ovl_check_encode_origin()
188 /* Lower file handle for non-upper non-decodable */ in ovl_check_encode_origin()
200 if (dentry == dentry->d_sb->s_root) in ovl_check_encode_origin()
204 * Upper decodable file handle for non-indexed upper. in ovl_check_encode_origin()
212 * lower dir or under a non-indexed upper is not always possible. in ovl_check_encode_origin()
219 /* Lower file handle for indexed and non-upper dir/non-dir */ in ovl_check_encode_origin()
262 struct ovl_fs *ofs = OVL_FS(inode->i_sb); in ovl_encode_fh()
287 * Find or instantiate an overlay dentry from real dentries and index.
294 struct dentry *lower = lowerpath ? lowerpath->dentry : NULL; in ovl_obtain_alias()
304 return ERR_PTR(-EIO); in ovl_obtain_alias()
308 return ERR_PTR(-ENOMEM); in ovl_obtain_alias()
312 ovl_lowerstack(oe)->dentry = dget(lower); in ovl_obtain_alias()
313 ovl_lowerstack(oe)->layer = lowerpath->layer; in ovl_obtain_alias()
340 if (lowerstack[i].layer->idx == idx) in ovl_dentry_real_at()
348 * Lookup a child overlay dentry to get a connected overlay dentry whose real
349 * dentry is @real. If @real is on upper layer, we lookup a child overlay
350 * dentry with the same name as the real dentry. Otherwise, we need to consult
354 struct dentry *real, in ovl_lookup_real_one() argument
363 * Lookup child overlay dentry by real name. The dir mutex protects us in ovl_lookup_real_one()
365 * real has already been moved to a parent that is not under the in ovl_lookup_real_one()
366 * connected overlay dir, we return -ECHILD and restart the lookup of in ovl_lookup_real_one()
367 * connected real path from the top. in ovl_lookup_real_one()
370 err = -ECHILD; in ovl_lookup_real_one()
371 parent = dget_parent(real); in ovl_lookup_real_one()
372 if (ovl_dentry_real_at(connected, layer->idx) != parent) in ovl_lookup_real_one()
376 * We also need to take a snapshot of real dentry name to protect us in ovl_lookup_real_one()
379 * pointer because we hold no lock on the real dentry. in ovl_lookup_real_one()
381 take_dentry_name_snapshot(&name, real); in ovl_lookup_real_one()
384 * permission checking altogether, but for now just use non-idmap in ovl_lookup_real_one()
392 } else if (!this || !this->d_inode) { in ovl_lookup_real_one()
394 err = -ENOENT; in ovl_lookup_real_one()
396 } else if (ovl_dentry_real_at(this, layer->idx) != real) { in ovl_lookup_real_one()
398 err = -ESTALE; in ovl_lookup_real_one()
408 pr_warn_ratelimited("failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n", in ovl_lookup_real_one()
409 real, layer->idx, connected, err); in ovl_lookup_real_one()
415 struct dentry *real,
419 * Lookup an indexed or hashed overlay dentry by real inode.
422 struct dentry *real, in ovl_lookup_real_inode() argument
434 inode = ovl_lookup_inode(sb, real, !layer->idx); in ovl_lookup_real_inode()
446 if (!this && layer->idx && ovl_indexdir(sb) && !WARN_ON(!d_is_dir(real))) { in ovl_lookup_real_inode()
447 index = ovl_lookup_index(ofs, NULL, real, false); in ovl_lookup_real_inode()
467 this = ovl_lookup_real(sb, upper, &ofs->layers[0]); in ovl_lookup_real_inode()
474 if (ovl_dentry_real_at(this, layer->idx) != real) { in ovl_lookup_real_inode()
476 this = ERR_PTR(-EIO); in ovl_lookup_real_inode()
483 * Lookup an indexed or hashed overlay dentry, whose real dentry is an
484 * ancestor of @real.
487 struct dentry *real, in ovl_lookup_real_ancestor() argument
491 struct dentry *ancestor = ERR_PTR(-EIO); in ovl_lookup_real_ancestor()
493 if (real == layer->mnt->mnt_root) in ovl_lookup_real_ancestor()
494 return dget(sb->s_root); in ovl_lookup_real_ancestor()
497 next = dget(real); in ovl_lookup_real_ancestor()
503 * cache or in index by real inode. in ovl_lookup_real_ancestor()
509 if (parent == layer->mnt->mnt_root) { in ovl_lookup_real_ancestor()
510 ancestor = dget(sb->s_root); in ovl_lookup_real_ancestor()
515 * If @real has been moved out of the layer root directory, in ovl_lookup_real_ancestor()
516 * we will eventully hit the real fs root. This cannot happen in ovl_lookup_real_ancestor()
520 ancestor = ERR_PTR(-EXDEV); in ovl_lookup_real_ancestor()
535 * Lookup a connected overlay dentry whose real dentry is @real.
536 * If @real is on upper layer, we lookup a child overlay dentry with the same
537 * path the real dentry. Otherwise, we need to consult index for lookup.
540 struct dentry *real, in ovl_lookup_real() argument
546 connected = ovl_lookup_real_ancestor(sb, real, layer); in ovl_lookup_real()
554 layer->idx); in ovl_lookup_real()
556 if (real_connected == real) in ovl_lookup_real()
560 next = dget(real); in ovl_lookup_real()
568 * If real has been moved out of 'real_connected', in ovl_lookup_real()
575 if (parent == layer->mnt->mnt_root) { in ovl_lookup_real()
577 connected = dget(sb->s_root); in ovl_lookup_real()
582 * If real file has been moved out of the layer root in ovl_lookup_real()
583 * directory, we will eventully hit the real fs root. in ovl_lookup_real()
588 err = -EXDEV; in ovl_lookup_real()
606 * still an ancestor of 'real'. There is a good chance in ovl_lookup_real()
611 if (err == -ECHILD) { in ovl_lookup_real()
612 this = ovl_lookup_real_ancestor(sb, real, in ovl_lookup_real()
632 pr_warn_ratelimited("failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n", in ovl_lookup_real()
633 real, layer->idx, connected, err); in ovl_lookup_real()
639 * Get an overlay dentry from upper/lower real dentries and index.
647 const struct ovl_layer *layer = upper ? &ofs->layers[0] : lowerpath->layer; in ovl_get_dentry()
648 struct dentry *real = upper ?: (index ?: lowerpath->dentry); in ovl_get_dentry() local
651 * Obtain a disconnected overlay dentry from a non-dir real dentry in ovl_get_dentry()
654 if (!d_is_dir(real)) in ovl_get_dentry()
658 if ((real->d_flags & DCACHE_DISCONNECTED) || d_unhashed(real)) in ovl_get_dentry()
659 return ERR_PTR(-ENOENT); in ovl_get_dentry()
662 * If real dentry is connected and hashed, get a connected overlay in ovl_get_dentry()
663 * dentry whose real dentry is @real. in ovl_get_dentry()
665 return ovl_lookup_real(sb, real, layer); in ovl_get_dentry()
676 return ERR_PTR(-EACCES); in ovl_upper_fh_to_d()
705 !(origin.dentry->d_flags & DCACHE_DISCONNECTED)) { in ovl_lower_fh_to_d()
755 /* Get a connected non-upper dir or disconnected non-dir */ in ovl_lower_fh_to_d()
772 /* If on-wire inner fid is aligned - nothing to do */ in ovl_fid_to_fh()
777 return ERR_PTR(-EINVAL); in ovl_fid_to_fh()
780 return ERR_PTR(-EINVAL); in ovl_fid_to_fh()
784 return ERR_PTR(-ENOMEM); in ovl_fid_to_fh()
787 memcpy(fh->buf, fid, buflen - OVL_FH_WIRE_OFFSET); in ovl_fid_to_fh()
809 flags = fh->fb.flags; in ovl_fh_to_dentry()
814 if (IS_ERR(dentry) && err != -ESTALE) in ovl_fh_to_dentry()
818 /* We may have needed to re-align OVL_FILEID_V0 */ in ovl_fh_to_dentry()
835 return ERR_PTR(-EACCES); in ovl_fh_to_parent()
846 return -EIO; in ovl_get_name()
856 return ERR_PTR(-EIO); in ovl_get_parent()
867 /* encode_fh() encodes non-decodable file handles with nfs_export=off */