Lines Matching +full:lower +full:- +full:case
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
38 * lower decoded dentry. This is done by following the overlay ancestry up to a
48 * copied up and renamed, upper dir /a will be indexed by lower dir /a from
51 * dentry from the connected lower dentry /a/b/c.
56 * and when the time comes to decode the file handle from lower dentry /a/b/c,
61 * entry /a in the lower layers above layer N and find the indexed dir /a from
63 * will need to verify there are no redirects in lower layers above N. In the
77 if (dentry == dentry->d_sb->s_root) in ovl_connectable_layer()
82 * lower layer in ovl_connectable_layer()
88 /* We can get upper/overlay path from indexed/lower dentry */ in ovl_connectable_layer()
89 return ovl_lowerstack(oe)->layer->idx; in ovl_connectable_layer()
94 * have the same uppermost lower layer as the origin's layer. We may need to
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
155 * copied up before NFS export was enabled. In that case we don't need to worry
157 * file handle. Overlay root dentry is a private case of non-indexed upper.
163 * --------------------------------
165 * Non-indexed upper | U
167 * Non-upper | L (*)
170 * L = lower file handle
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.
174 * To mitigate those case, we may copy up the lower dir ancestor before encode
175 * of a decodable file handle for non-upper dir.
177 * Return 0 for upper file handle, > 0 for lower file handle or < 0 on error.
181 struct ovl_fs *ofs = OVL_FS(inode->i_sb); in ovl_check_encode_origin()
182 bool decodable = ofs->config.nfs_export; in ovl_check_encode_origin()
190 /* Lower file handle for non-upper non-decodable */ in ovl_check_encode_origin()
202 if (inode == d_inode(inode->i_sb->s_root)) in ovl_check_encode_origin()
206 * Upper decodable file handle for non-indexed upper. in ovl_check_encode_origin()
214 * lower dir or under a non-indexed upper is not always possible. in ovl_check_encode_origin()
218 if (!decodable || !S_ISDIR(inode->i_mode)) in ovl_check_encode_origin()
223 return -ENOENT; in ovl_check_encode_origin()
230 /* Lower file handle for indexed and non-upper dir/non-dir */ in ovl_check_encode_origin()
242 * Check if we should encode a lower or upper file handle and maybe in ovl_dentry_to_fid()
243 * copy up an ancestor to make lower file handle connectable. in ovl_dentry_to_fid()
249 /* Encode an upper or lower file handle */ in ovl_dentry_to_fid()
266 inode->i_ino, err); in ovl_dentry_to_fid()
273 struct ovl_fs *ofs = OVL_FS(inode->i_sb); in ovl_encode_fh()
299 struct dentry *lower = lowerpath ? lowerpath->dentry : NULL; in ovl_obtain_alias() local
308 if (d_is_dir(upper ?: lower)) in ovl_obtain_alias()
309 return ERR_PTR(-EIO); in ovl_obtain_alias()
311 oe = ovl_alloc_entry(!!lower); in ovl_obtain_alias()
313 return ERR_PTR(-ENOMEM); in ovl_obtain_alias()
316 if (lower) { in ovl_obtain_alias()
317 ovl_lowerstack(oe)->dentry = dget(lower); in ovl_obtain_alias()
318 ovl_lowerstack(oe)->layer = lowerpath->layer; in ovl_obtain_alias()
334 /* Get the upper or lower dentry in stack whose on layer @idx */
345 if (lowerstack[i].layer->idx == idx) in ovl_dentry_real_at()
371 * connected overlay dir, we return -ECHILD and restart the lookup of in ovl_lookup_real_one()
375 err = -ECHILD; in ovl_lookup_real_one()
377 if (ovl_dentry_real_at(connected, layer->idx) != parent) in ovl_lookup_real_one()
382 * from racing with underlying layer rename. In this case, we don't in ovl_lookup_real_one()
389 * permission checking altogether, but for now just use non-idmap in ovl_lookup_real_one()
397 } else if (!this || !this->d_inode) { in ovl_lookup_real_one()
399 err = -ENOENT; in ovl_lookup_real_one()
401 } else if (ovl_dentry_real_at(this, layer->idx) != real) { in ovl_lookup_real_one()
403 err = -ESTALE; in ovl_lookup_real_one()
414 real, layer->idx, connected, err); in ovl_lookup_real_one()
439 inode = ovl_lookup_inode(sb, real, !layer->idx); in ovl_lookup_real_inode()
448 * For decoded lower dir file handle, lookup index by origin to check in ovl_lookup_real_inode()
449 * if lower dir was copied up and and/or removed. in ovl_lookup_real_inode()
451 if (!this && layer->idx && ovl_indexdir(sb) && !WARN_ON(!d_is_dir(real))) { in ovl_lookup_real_inode()
466 * ovl_lookup_real() in lower layer may call recursively once to in ovl_lookup_real_inode()
468 * back lower parents to the topmost indexed parent. The second in ovl_lookup_real_inode()
472 this = ovl_lookup_real(sb, upper, &ofs->layers[0]); in ovl_lookup_real_inode()
479 if (ovl_dentry_real_at(this, layer->idx) != real) { in ovl_lookup_real_inode()
481 this = ERR_PTR(-EIO); in ovl_lookup_real_inode()
496 struct dentry *ancestor = ERR_PTR(-EIO); in ovl_lookup_real_ancestor()
498 if (real == layer->mnt->mnt_root) in ovl_lookup_real_ancestor()
499 return dget(sb->s_root); in ovl_lookup_real_ancestor()
514 if (parent == layer->mnt->mnt_root) { in ovl_lookup_real_ancestor()
515 ancestor = dget(sb->s_root); in ovl_lookup_real_ancestor()
522 * by legit overlay rename, so we return error in that case. in ovl_lookup_real_ancestor()
525 ancestor = ERR_PTR(-EXDEV); in ovl_lookup_real_ancestor()
559 layer->idx); in ovl_lookup_real()
575 * root. In that case, we need to restart connecting. in ovl_lookup_real()
576 * This game can go on forever in the worst case. We in ovl_lookup_real()
580 if (parent == layer->mnt->mnt_root) { in ovl_lookup_real()
582 connected = dget(sb->s_root); in ovl_lookup_real()
590 * return error in that case. in ovl_lookup_real()
593 err = -EXDEV; in ovl_lookup_real()
609 * In this case, we need to restart the lookup from the in ovl_lookup_real()
616 if (err == -ECHILD) { in ovl_lookup_real()
638 real, layer->idx, connected, err); in ovl_lookup_real()
644 * Get an overlay dentry from upper/lower real dentries and index.
652 const struct ovl_layer *layer = upper ? &ofs->layers[0] : lowerpath->layer; in ovl_get_dentry()
653 struct dentry *real = upper ?: (index ?: lowerpath->dentry); in ovl_get_dentry()
656 * Obtain a disconnected overlay dentry from a non-dir real dentry in ovl_get_dentry()
663 if ((real->d_flags & DCACHE_DISCONNECTED) || d_unhashed(real)) in ovl_get_dentry()
664 return ERR_PTR(-ENOENT); in ovl_get_dentry()
681 return ERR_PTR(-EACCES); in ovl_upper_fh_to_d()
710 !(origin.dentry->d_flags & DCACHE_DISCONNECTED)) { in ovl_lower_fh_to_d()
760 /* Get a connected non-upper dir or disconnected non-dir */ in ovl_lower_fh_to_d()
777 /* If on-wire inner fid is aligned - nothing to do */ in ovl_fid_to_fh()
782 return ERR_PTR(-EINVAL); in ovl_fid_to_fh()
785 return ERR_PTR(-EINVAL); in ovl_fid_to_fh()
789 return ERR_PTR(-ENOMEM); in ovl_fid_to_fh()
792 memcpy(fh->buf, fid, buflen - OVL_FH_WIRE_OFFSET); in ovl_fid_to_fh()
814 flags = fh->fb.flags; in ovl_fh_to_dentry()
819 if (IS_ERR(dentry) && err != -ESTALE) in ovl_fh_to_dentry()
823 /* We may have needed to re-align OVL_FILEID_V0 */ in ovl_fh_to_dentry()
840 return ERR_PTR(-EACCES); in ovl_fh_to_parent()
851 return -EIO; in ovl_get_name()
861 return ERR_PTR(-EIO); in ovl_get_parent()
872 /* encode_fh() encodes non-decodable file handles with nfs_export=off */