Lines Matching +full:connected +full:- +full:positive
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
39 * "layer N connected" ancestor and verifying that all parents along the way are
42 * making that ancestor "layer N connected". For example:
50 * in ovl_lookup_real_ancestor() will not be able to lookup a connected overlay
51 * dentry from the connected lower dentry /a/b/c.
55 * /a/b. After copy up (and index) of /a/b, it will become "layer 2 connected"
58 * a connected overlay dentry will be accomplished.
62 * layer 1. If that improvement is made, then the check for "layer N connected"
77 if (dentry == dentry->d_sb->s_root) in ovl_connectable_layer()
89 return ovl_lowerstack(oe)->layer->idx; in ovl_connectable_layer()
93 * @dentry is "connected" if all ancestors up to root or a "connected" ancestor
95 * copy up a "connectable" ancestor to make it "connected". A "connected" dentry
96 * cannot become non "connected", so cache positive result in dentry flags.
98 * Return the connected origin layer or < 0 on error.
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()
133 /* If @parent is connected or indexed we are done */ 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()
184 /* Lower file handle for non-upper non-decodable */ in ovl_check_encode_origin()
196 if (dentry == dentry->d_sb->s_root) in ovl_check_encode_origin()
200 * Upper decodable file handle for non-indexed upper. in ovl_check_encode_origin()
208 * lower dir or under a non-indexed upper is not always possible. in ovl_check_encode_origin()
209 * ovl_connect_layer() will try to make origin's layer "connected" by in ovl_check_encode_origin()
215 /* Lower file handle for indexed and non-upper dir/non-dir */ in ovl_check_encode_origin()
258 struct ovl_fs *ofs = OVL_FS(inode->i_sb); in ovl_encode_fh()
290 struct dentry *lower = lowerpath ? lowerpath->dentry : NULL; in ovl_obtain_alias()
300 return ERR_PTR(-EIO); in ovl_obtain_alias()
304 return ERR_PTR(-ENOMEM); in ovl_obtain_alias()
308 ovl_lowerstack(oe)->dentry = dget(lower); in ovl_obtain_alias()
309 ovl_lowerstack(oe)->layer = lowerpath->layer; in ovl_obtain_alias()
336 if (lowerstack[i].layer->idx == idx) in ovl_dentry_real_at()
344 * Lookup a child overlay dentry to get a connected overlay dentry whose real
349 static struct dentry *ovl_lookup_real_one(struct dentry *connected, in ovl_lookup_real_one() argument
353 struct inode *dir = d_inode(connected); in ovl_lookup_real_one()
362 * connected overlay dir, we return -ECHILD and restart the lookup of in ovl_lookup_real_one()
363 * connected real path from the top. in ovl_lookup_real_one()
366 err = -ECHILD; in ovl_lookup_real_one()
368 if (ovl_dentry_real_at(connected, layer->idx) != parent) in ovl_lookup_real_one()
380 * permission checking altogether, but for now just use non-idmap in ovl_lookup_real_one()
383 this = lookup_one_len(name.name.name, connected, name.name.len); in ovl_lookup_real_one()
388 } else if (!this || !this->d_inode) { in ovl_lookup_real_one()
390 err = -ENOENT; in ovl_lookup_real_one()
392 } else if (ovl_dentry_real_at(this, layer->idx) != real) { in ovl_lookup_real_one()
394 err = -ESTALE; in ovl_lookup_real_one()
404 pr_warn_ratelimited("failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n", in ovl_lookup_real_one()
405 real, layer->idx, connected, err); in ovl_lookup_real_one()
430 inode = ovl_lookup_inode(sb, real, !layer->idx); in ovl_lookup_real_inode()
442 if (!this && layer->idx && ovl_indexdir(sb) && !WARN_ON(!d_is_dir(real))) { in ovl_lookup_real_inode()
448 /* Get connected upper overlay dir from index */ in ovl_lookup_real_inode()
461 * connected/hashed upper parent (or up to root). in ovl_lookup_real_inode()
463 this = ovl_lookup_real(sb, upper, &ofs->layers[0]); in ovl_lookup_real_inode()
470 if (ovl_dentry_real_at(this, layer->idx) != real) { in ovl_lookup_real_inode()
472 this = ERR_PTR(-EIO); in ovl_lookup_real_inode()
487 struct dentry *ancestor = ERR_PTR(-EIO); in ovl_lookup_real_ancestor()
489 if (real == layer->mnt->mnt_root) in ovl_lookup_real_ancestor()
490 return dget(sb->s_root); in ovl_lookup_real_ancestor()
505 if (parent == layer->mnt->mnt_root) { in ovl_lookup_real_ancestor()
506 ancestor = dget(sb->s_root); in ovl_lookup_real_ancestor()
516 ancestor = ERR_PTR(-EXDEV); in ovl_lookup_real_ancestor()
531 * Lookup a connected overlay dentry whose real dentry is @real.
539 struct dentry *connected; in ovl_lookup_real() local
542 connected = ovl_lookup_real_ancestor(sb, real, layer); in ovl_lookup_real()
543 if (IS_ERR(connected)) in ovl_lookup_real()
544 return connected; in ovl_lookup_real()
549 struct dentry *real_connected = ovl_dentry_real_at(connected, in ovl_lookup_real()
550 layer->idx); in ovl_lookup_real()
555 /* Find the topmost dentry not yet connected */ in ovl_lookup_real()
571 if (parent == layer->mnt->mnt_root) { in ovl_lookup_real()
572 dput(connected); in ovl_lookup_real()
573 connected = dget(sb->s_root); in ovl_lookup_real()
584 err = -EXDEV; in ovl_lookup_real()
593 this = ovl_lookup_real_one(connected, next, layer); in ovl_lookup_real()
599 * overlay rename of child away from 'connected' parent. in ovl_lookup_real()
607 if (err == -ECHILD) { in ovl_lookup_real()
613 dput(connected); in ovl_lookup_real()
614 connected = this; in ovl_lookup_real()
625 return connected; in ovl_lookup_real()
628 pr_warn_ratelimited("failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n", in ovl_lookup_real()
629 real, layer->idx, connected, err); in ovl_lookup_real()
630 dput(connected); in ovl_lookup_real()
643 const struct ovl_layer *layer = upper ? &ofs->layers[0] : lowerpath->layer; in ovl_get_dentry()
644 struct dentry *real = upper ?: (index ?: lowerpath->dentry); in ovl_get_dentry()
647 * Obtain a disconnected overlay dentry from a non-dir real dentry in ovl_get_dentry()
654 if ((real->d_flags & DCACHE_DISCONNECTED) || d_unhashed(real)) in ovl_get_dentry()
655 return ERR_PTR(-ENOENT); in ovl_get_dentry()
658 * If real dentry is connected and hashed, get a connected overlay in ovl_get_dentry()
672 return ERR_PTR(-EACCES); in ovl_upper_fh_to_d()
701 !(origin.dentry->d_flags & DCACHE_DISCONNECTED)) { in ovl_lower_fh_to_d()
724 /* Then try to get a connected upper dir by index */ in ovl_lower_fh_to_d()
751 /* Get a connected non-upper dir or disconnected non-dir */ in ovl_lower_fh_to_d()
768 /* If on-wire inner fid is aligned - nothing to do */ in ovl_fid_to_fh()
773 return ERR_PTR(-EINVAL); in ovl_fid_to_fh()
776 return ERR_PTR(-EINVAL); in ovl_fid_to_fh()
780 return ERR_PTR(-ENOMEM); in ovl_fid_to_fh()
783 memcpy(fh->buf, fid, buflen - OVL_FH_WIRE_OFFSET); in ovl_fid_to_fh()
805 flags = fh->fb.flags; in ovl_fh_to_dentry()
810 if (IS_ERR(dentry) && err != -ESTALE) in ovl_fh_to_dentry()
814 /* We may have needed to re-align OVL_FILEID_V0 */ in ovl_fh_to_dentry()
831 return ERR_PTR(-EACCES); in ovl_fh_to_parent()
838 * ovl_fh_to_dentry() returns connected dir overlay dentries and in ovl_get_name()
842 return -EIO; in ovl_get_name()
848 * ovl_fh_to_dentry() returns connected dir overlay dentries, so we in ovl_get_parent()
852 return ERR_PTR(-EIO); in ovl_get_parent()
863 /* encode_fh() encodes non-decodable file handles with nfs_export=off */