export.c (16aac5ad1fa94894b798dd522c5c3a6a0628d7f0) export.c (f01d08899fd7fa808ff9b8d33ca4882ab44d42fa)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Overlayfs NFS export support.
4 *
5 * Amir Goldstein <amir73il@gmail.com>
6 *
7 * Copyright (C) 2017-2018 CTERA Networks. All Rights Reserved.
8 */

--- 169 unchanged lines hidden (view full) ---

178 * possible when there are redirects in lower layers and non-indexed merge dirs.
179 * To mitigate those case, we may copy up the lower dir ancestor before encode
180 * of a decodable file handle for non-upper dir.
181 *
182 * Return 0 for upper file handle, > 0 for lower file handle or < 0 on error.
183 */
184static int ovl_check_encode_origin(struct dentry *dentry)
185{
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Overlayfs NFS export support.
4 *
5 * Amir Goldstein <amir73il@gmail.com>
6 *
7 * Copyright (C) 2017-2018 CTERA Networks. All Rights Reserved.
8 */

--- 169 unchanged lines hidden (view full) ---

178 * possible when there are redirects in lower layers and non-indexed merge dirs.
179 * To mitigate those case, we may copy up the lower dir ancestor before encode
180 * of a decodable file handle for non-upper dir.
181 *
182 * Return 0 for upper file handle, > 0 for lower file handle or < 0 on error.
183 */
184static int ovl_check_encode_origin(struct dentry *dentry)
185{
186 struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
186 struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
187 bool decodable = ofs->config.nfs_export;
188
189 /* Lower file handle for non-upper non-decodable */
190 if (!ovl_dentry_upper(dentry) && !decodable)
191 return 0;
192
193 /* Upper file handle for pure upper */
194 if (!ovl_dentry_lower(dentry))

--- 244 unchanged lines hidden (view full) ---

439
440/*
441 * Lookup an indexed or hashed overlay dentry by real inode.
442 */
443static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
444 struct dentry *real,
445 const struct ovl_layer *layer)
446{
187 bool decodable = ofs->config.nfs_export;
188
189 /* Lower file handle for non-upper non-decodable */
190 if (!ovl_dentry_upper(dentry) && !decodable)
191 return 0;
192
193 /* Upper file handle for pure upper */
194 if (!ovl_dentry_lower(dentry))

--- 244 unchanged lines hidden (view full) ---

439
440/*
441 * Lookup an indexed or hashed overlay dentry by real inode.
442 */
443static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
444 struct dentry *real,
445 const struct ovl_layer *layer)
446{
447 struct ovl_fs *ofs = sb->s_fs_info;
447 struct ovl_fs *ofs = OVL_FS(sb);
448 struct dentry *index = NULL;
449 struct dentry *this = NULL;
450 struct inode *inode;
451
452 /*
453 * Decoding upper dir from index is expensive, so first try to lookup
454 * overlay dentry in inode/dcache.
455 */

--- 204 unchanged lines hidden (view full) ---

660/*
661 * Get an overlay dentry from upper/lower real dentries and index.
662 */
663static struct dentry *ovl_get_dentry(struct super_block *sb,
664 struct dentry *upper,
665 struct ovl_path *lowerpath,
666 struct dentry *index)
667{
448 struct dentry *index = NULL;
449 struct dentry *this = NULL;
450 struct inode *inode;
451
452 /*
453 * Decoding upper dir from index is expensive, so first try to lookup
454 * overlay dentry in inode/dcache.
455 */

--- 204 unchanged lines hidden (view full) ---

660/*
661 * Get an overlay dentry from upper/lower real dentries and index.
662 */
663static struct dentry *ovl_get_dentry(struct super_block *sb,
664 struct dentry *upper,
665 struct ovl_path *lowerpath,
666 struct dentry *index)
667{
668 struct ovl_fs *ofs = sb->s_fs_info;
668 struct ovl_fs *ofs = OVL_FS(sb);
669 const struct ovl_layer *layer = upper ? &ofs->layers[0] : lowerpath->layer;
670 struct dentry *real = upper ?: (index ?: lowerpath->dentry);
671
672 /*
673 * Obtain a disconnected overlay dentry from a non-dir real dentry
674 * and index.
675 */
676 if (!d_is_dir(real))

--- 8 unchanged lines hidden (view full) ---

685 * dentry whose real dentry is @real.
686 */
687 return ovl_lookup_real(sb, real, layer);
688}
689
690static struct dentry *ovl_upper_fh_to_d(struct super_block *sb,
691 struct ovl_fh *fh)
692{
669 const struct ovl_layer *layer = upper ? &ofs->layers[0] : lowerpath->layer;
670 struct dentry *real = upper ?: (index ?: lowerpath->dentry);
671
672 /*
673 * Obtain a disconnected overlay dentry from a non-dir real dentry
674 * and index.
675 */
676 if (!d_is_dir(real))

--- 8 unchanged lines hidden (view full) ---

685 * dentry whose real dentry is @real.
686 */
687 return ovl_lookup_real(sb, real, layer);
688}
689
690static struct dentry *ovl_upper_fh_to_d(struct super_block *sb,
691 struct ovl_fh *fh)
692{
693 struct ovl_fs *ofs = sb->s_fs_info;
693 struct ovl_fs *ofs = OVL_FS(sb);
694 struct dentry *dentry;
695 struct dentry *upper;
696
697 if (!ovl_upper_mnt(ofs))
698 return ERR_PTR(-EACCES);
699
700 upper = ovl_decode_real_fh(ofs, fh, ovl_upper_mnt(ofs), true);
701 if (IS_ERR_OR_NULL(upper))
702 return upper;
703
704 dentry = ovl_get_dentry(sb, upper, NULL, NULL);
705 dput(upper);
706
707 return dentry;
708}
709
710static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
711 struct ovl_fh *fh)
712{
694 struct dentry *dentry;
695 struct dentry *upper;
696
697 if (!ovl_upper_mnt(ofs))
698 return ERR_PTR(-EACCES);
699
700 upper = ovl_decode_real_fh(ofs, fh, ovl_upper_mnt(ofs), true);
701 if (IS_ERR_OR_NULL(upper))
702 return upper;
703
704 dentry = ovl_get_dentry(sb, upper, NULL, NULL);
705 dput(upper);
706
707 return dentry;
708}
709
710static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
711 struct ovl_fh *fh)
712{
713 struct ovl_fs *ofs = sb->s_fs_info;
713 struct ovl_fs *ofs = OVL_FS(sb);
714 struct ovl_path origin = { };
715 struct ovl_path *stack = &origin;
716 struct dentry *dentry = NULL;
717 struct dentry *index = NULL;
718 struct inode *inode;
719 int err;
720
721 /* First lookup overlay inode in inode cache by origin fh */

--- 171 unchanged lines hidden ---
714 struct ovl_path origin = { };
715 struct ovl_path *stack = &origin;
716 struct dentry *dentry = NULL;
717 struct dentry *index = NULL;
718 struct inode *inode;
719 int err;
720
721 /* First lookup overlay inode in inode cache by origin fh */

--- 171 unchanged lines hidden ---