Skip to content

Commit 719ea86

Browse files
committed
Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
Pull overlayfs fixes from Miklos Szeredi: "This fixes a corner case for NFS exporting (introduced in this cycle) as well as fixing miscellaneous bugs" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: update Kconfig texts ovl: redirect_dir=nofollow should not follow redirect for opaque lower ovl: fix ptr_ret.cocci warnings ovl: check ERR_PTR() return value from ovl_lookup_real() ovl: check lower ancestry on encode of lower dir file handle ovl: hash non-dir by lower inode for fsnotify
2 parents 2d9b1d6 + 36cd95d commit 719ea86

File tree

6 files changed

+228
-68
lines changed

6 files changed

+228
-68
lines changed

fs/overlayfs/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ config OVERLAY_FS_REDIRECT_DIR
2424
an overlay which has redirects on a kernel that doesn't support this
2525
feature will have unexpected results.
2626

27+
If unsure, say N.
28+
2729
config OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW
2830
bool "Overlayfs: follow redirects even if redirects are turned off"
2931
default y
@@ -32,8 +34,13 @@ config OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW
3234
Disable this to get a possibly more secure configuration, but that
3335
might not be backward compatible with previous kernels.
3436

37+
If backward compatibility is not an issue, then it is safe and
38+
recommended to say N here.
39+
3540
For more information, see Documentation/filesystems/overlayfs.txt
3641

42+
If unsure, say Y.
43+
3744
config OVERLAY_FS_INDEX
3845
bool "Overlayfs: turn on inodes index feature by default"
3946
depends on OVERLAY_FS
@@ -51,6 +58,8 @@ config OVERLAY_FS_INDEX
5158
That is, mounting an overlay which has an inodes index on a kernel
5259
that doesn't support this feature will have unexpected results.
5360

61+
If unsure, say N.
62+
5463
config OVERLAY_FS_NFS_EXPORT
5564
bool "Overlayfs: turn on NFS export feature by default"
5665
depends on OVERLAY_FS
@@ -72,3 +81,8 @@ config OVERLAY_FS_NFS_EXPORT
7281
Note, that the NFS export feature is not backward compatible.
7382
That is, mounting an overlay which has a full index on a kernel
7483
that doesn't support this feature will have unexpected results.
84+
85+
Most users should say N here and enable this feature on a case-by-
86+
case basis with the "nfs_export=on" mount option.
87+
88+
Say N unless you fully understand the consequences.

fs/overlayfs/export.c

Lines changed: 169 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,142 @@
1919
#include <linux/ratelimit.h>
2020
#include "overlayfs.h"
2121

22+
static int ovl_encode_maybe_copy_up(struct dentry *dentry)
23+
{
24+
int err;
25+
26+
if (ovl_dentry_upper(dentry))
27+
return 0;
28+
29+
err = ovl_want_write(dentry);
30+
if (!err) {
31+
err = ovl_copy_up(dentry);
32+
ovl_drop_write(dentry);
33+
}
34+
35+
if (err) {
36+
pr_warn_ratelimited("overlayfs: failed to copy up on encode (%pd2, err=%i)\n",
37+
dentry, err);
38+
}
39+
40+
return err;
41+
}
42+
43+
/*
44+
* Before encoding a non-upper directory file handle from real layer N, we need
45+
* to check if it will be possible to reconnect an overlay dentry from the real
46+
* lower decoded dentry. This is done by following the overlay ancestry up to a
47+
* "layer N connected" ancestor and verifying that all parents along the way are
48+
* "layer N connectable". If an ancestor that is NOT "layer N connectable" is
49+
* found, we need to copy up an ancestor, which is "layer N connectable", thus
50+
* making that ancestor "layer N connected". For example:
51+
*
52+
* layer 1: /a
53+
* layer 2: /a/b/c
54+
*
55+
* The overlay dentry /a is NOT "layer 2 connectable", because if dir /a is
56+
* copied up and renamed, upper dir /a will be indexed by lower dir /a from
57+
* layer 1. The dir /a from layer 2 will never be indexed, so the algorithm (*)
58+
* in ovl_lookup_real_ancestor() will not be able to lookup a connected overlay
59+
* dentry from the connected lower dentry /a/b/c.
60+
*
61+
* To avoid this problem on decode time, we need to copy up an ancestor of
62+
* /a/b/c, which is "layer 2 connectable", on encode time. That ancestor is
63+
* /a/b. After copy up (and index) of /a/b, it will become "layer 2 connected"
64+
* and when the time comes to decode the file handle from lower dentry /a/b/c,
65+
* ovl_lookup_real_ancestor() will find the indexed ancestor /a/b and decoding
66+
* a connected overlay dentry will be accomplished.
67+
*
68+
* (*) the algorithm in ovl_lookup_real_ancestor() can be improved to lookup an
69+
* entry /a in the lower layers above layer N and find the indexed dir /a from
70+
* layer 1. If that improvement is made, then the check for "layer N connected"
71+
* will need to verify there are no redirects in lower layers above N. In the
72+
* example above, /a will be "layer 2 connectable". However, if layer 2 dir /a
73+
* is a target of a layer 1 redirect, then /a will NOT be "layer 2 connectable":
74+
*
75+
* layer 1: /A (redirect = /a)
76+
* layer 2: /a/b/c
77+
*/
78+
79+
/* Return the lowest layer for encoding a connectable file handle */
80+
static int ovl_connectable_layer(struct dentry *dentry)
81+
{
82+
struct ovl_entry *oe = OVL_E(dentry);
83+
84+
/* We can get overlay root from root of any layer */
85+
if (dentry == dentry->d_sb->s_root)
86+
return oe->numlower;
87+
88+
/*
89+
* If it's an unindexed merge dir, then it's not connectable with any
90+
* lower layer
91+
*/
92+
if (ovl_dentry_upper(dentry) &&
93+
!ovl_test_flag(OVL_INDEX, d_inode(dentry)))
94+
return 0;
95+
96+
/* We can get upper/overlay path from indexed/lower dentry */
97+
return oe->lowerstack[0].layer->idx;
98+
}
99+
100+
/*
101+
* @dentry is "connected" if all ancestors up to root or a "connected" ancestor
102+
* have the same uppermost lower layer as the origin's layer. We may need to
103+
* copy up a "connectable" ancestor to make it "connected". A "connected" dentry
104+
* cannot become non "connected", so cache positive result in dentry flags.
105+
*
106+
* Return the connected origin layer or < 0 on error.
107+
*/
108+
static int ovl_connect_layer(struct dentry *dentry)
109+
{
110+
struct dentry *next, *parent = NULL;
111+
int origin_layer;
112+
int err = 0;
113+
114+
if (WARN_ON(dentry == dentry->d_sb->s_root) ||
115+
WARN_ON(!ovl_dentry_lower(dentry)))
116+
return -EIO;
117+
118+
origin_layer = OVL_E(dentry)->lowerstack[0].layer->idx;
119+
if (ovl_dentry_test_flag(OVL_E_CONNECTED, dentry))
120+
return origin_layer;
121+
122+
/* Find the topmost origin layer connectable ancestor of @dentry */
123+
next = dget(dentry);
124+
for (;;) {
125+
parent = dget_parent(next);
126+
if (WARN_ON(parent == next)) {
127+
err = -EIO;
128+
break;
129+
}
130+
131+
/*
132+
* If @parent is not origin layer connectable, then copy up
133+
* @next which is origin layer connectable and we are done.
134+
*/
135+
if (ovl_connectable_layer(parent) < origin_layer) {
136+
err = ovl_encode_maybe_copy_up(next);
137+
break;
138+
}
139+
140+
/* If @parent is connected or indexed we are done */
141+
if (ovl_dentry_test_flag(OVL_E_CONNECTED, parent) ||
142+
ovl_test_flag(OVL_INDEX, d_inode(parent)))
143+
break;
144+
145+
dput(next);
146+
next = parent;
147+
}
148+
149+
dput(parent);
150+
dput(next);
151+
152+
if (!err)
153+
ovl_dentry_set_flag(OVL_E_CONNECTED, dentry);
154+
155+
return err ?: origin_layer;
156+
}
157+
22158
/*
23159
* We only need to encode origin if there is a chance that the same object was
24160
* encoded pre copy up and then we need to stay consistent with the same
@@ -41,73 +177,59 @@
41177
* L = lower file handle
42178
*
43179
* (*) Connecting an overlay dir from real lower dentry is not always
44-
* possible when there are redirects in lower layers. To mitigate this case,
45-
* we copy up the lower dir first and then encode an upper dir file handle.
180+
* possible when there are redirects in lower layers and non-indexed merge dirs.
181+
* To mitigate those case, we may copy up the lower dir ancestor before encode
182+
* a lower dir file handle.
183+
*
184+
* Return 0 for upper file handle, > 0 for lower file handle or < 0 on error.
46185
*/
47-
static bool ovl_should_encode_origin(struct dentry *dentry)
186+
static int ovl_check_encode_origin(struct dentry *dentry)
48187
{
49188
struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
50189

190+
/* Upper file handle for pure upper */
51191
if (!ovl_dentry_lower(dentry))
52-
return false;
192+
return 0;
53193

54194
/*
55-
* Decoding a merge dir, whose origin's parent is under a redirected
56-
* lower dir is not always possible. As a simple aproximation, we do
57-
* not encode lower dir file handles when overlay has multiple lower
58-
* layers and origin is below the topmost lower layer.
195+
* Upper file handle for non-indexed upper.
59196
*
60-
* TODO: copy up only the parent that is under redirected lower.
197+
* Root is never indexed, so if there's an upper layer, encode upper for
198+
* root.
61199
*/
62-
if (d_is_dir(dentry) && ofs->upper_mnt &&
63-
OVL_E(dentry)->lowerstack[0].layer->idx > 1)
64-
return false;
65-
66-
/* Decoding a non-indexed upper from origin is not implemented */
67200
if (ovl_dentry_upper(dentry) &&
68201
!ovl_test_flag(OVL_INDEX, d_inode(dentry)))
69-
return false;
70-
71-
return true;
72-
}
73-
74-
static int ovl_encode_maybe_copy_up(struct dentry *dentry)
75-
{
76-
int err;
77-
78-
if (ovl_dentry_upper(dentry))
79202
return 0;
80203

81-
err = ovl_want_write(dentry);
82-
if (err)
83-
return err;
84-
85-
err = ovl_copy_up(dentry);
204+
/*
205+
* Decoding a merge dir, whose origin's ancestor is under a redirected
206+
* lower dir or under a non-indexed upper is not always possible.
207+
* ovl_connect_layer() will try to make origin's layer "connected" by
208+
* copying up a "connectable" ancestor.
209+
*/
210+
if (d_is_dir(dentry) && ofs->upper_mnt)
211+
return ovl_connect_layer(dentry);
86212

87-
ovl_drop_write(dentry);
88-
return err;
213+
/* Lower file handle for indexed and non-upper dir/non-dir */
214+
return 1;
89215
}
90216

91217
static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
92218
{
93-
struct dentry *origin = ovl_dentry_lower(dentry);
94219
struct ovl_fh *fh = NULL;
95-
int err;
220+
int err, enc_lower;
96221

97222
/*
98-
* If we should not encode a lower dir file handle, copy up and encode
99-
* an upper dir file handle.
223+
* Check if we should encode a lower or upper file handle and maybe
224+
* copy up an ancestor to make lower file handle connectable.
100225
*/
101-
if (!ovl_should_encode_origin(dentry)) {
102-
err = ovl_encode_maybe_copy_up(dentry);
103-
if (err)
104-
goto fail;
105-
106-
origin = NULL;
107-
}
226+
err = enc_lower = ovl_check_encode_origin(dentry);
227+
if (enc_lower < 0)
228+
goto fail;
108229

109-
/* Encode an upper or origin file handle */
110-
fh = ovl_encode_fh(origin ?: ovl_dentry_upper(dentry), !origin);
230+
/* Encode an upper or lower file handle */
231+
fh = ovl_encode_fh(enc_lower ? ovl_dentry_lower(dentry) :
232+
ovl_dentry_upper(dentry), !enc_lower);
111233
err = PTR_ERR(fh);
112234
if (IS_ERR(fh))
113235
goto fail;
@@ -355,8 +477,8 @@ static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
355477
dput(upper);
356478
}
357479

358-
if (!this)
359-
return NULL;
480+
if (IS_ERR_OR_NULL(this))
481+
return this;
360482

361483
if (WARN_ON(ovl_dentry_real_at(this, layer->idx) != real)) {
362484
dput(this);
@@ -498,7 +620,7 @@ static struct dentry *ovl_lookup_real(struct super_block *sb,
498620
if (err == -ECHILD) {
499621
this = ovl_lookup_real_ancestor(sb, real,
500622
layer);
501-
err = IS_ERR(this) ? PTR_ERR(this) : 0;
623+
err = PTR_ERR_OR_ZERO(this);
502624
}
503625
if (!err) {
504626
dput(connected);

fs/overlayfs/inode.c

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -669,38 +669,59 @@ struct inode *ovl_lookup_inode(struct super_block *sb, struct dentry *real,
669669
return inode;
670670
}
671671

672+
/*
673+
* Does overlay inode need to be hashed by lower inode?
674+
*/
675+
static bool ovl_hash_bylower(struct super_block *sb, struct dentry *upper,
676+
struct dentry *lower, struct dentry *index)
677+
{
678+
struct ovl_fs *ofs = sb->s_fs_info;
679+
680+
/* No, if pure upper */
681+
if (!lower)
682+
return false;
683+
684+
/* Yes, if already indexed */
685+
if (index)
686+
return true;
687+
688+
/* Yes, if won't be copied up */
689+
if (!ofs->upper_mnt)
690+
return true;
691+
692+
/* No, if lower hardlink is or will be broken on copy up */
693+
if ((upper || !ovl_indexdir(sb)) &&
694+
!d_is_dir(lower) && d_inode(lower)->i_nlink > 1)
695+
return false;
696+
697+
/* No, if non-indexed upper with NFS export */
698+
if (sb->s_export_op && upper)
699+
return false;
700+
701+
/* Otherwise, hash by lower inode for fsnotify */
702+
return true;
703+
}
704+
672705
struct inode *ovl_get_inode(struct super_block *sb, struct dentry *upperdentry,
673706
struct dentry *lowerdentry, struct dentry *index,
674707
unsigned int numlower)
675708
{
676-
struct ovl_fs *ofs = sb->s_fs_info;
677709
struct inode *realinode = upperdentry ? d_inode(upperdentry) : NULL;
678710
struct inode *inode;
679-
/* Already indexed or could be indexed on copy up? */
680-
bool indexed = (index || (ovl_indexdir(sb) && !upperdentry));
681-
struct dentry *origin = indexed ? lowerdentry : NULL;
711+
bool bylower = ovl_hash_bylower(sb, upperdentry, lowerdentry, index);
682712
bool is_dir;
683713

684-
if (WARN_ON(upperdentry && indexed && !lowerdentry))
685-
return ERR_PTR(-EIO);
686-
687714
if (!realinode)
688715
realinode = d_inode(lowerdentry);
689716

690717
/*
691-
* Copy up origin (lower) may exist for non-indexed non-dir upper, but
692-
* we must not use lower as hash key in that case.
693-
* Hash non-dir that is or could be indexed by origin inode.
694-
* Hash dir that is or could be merged by origin inode.
695-
* Hash pure upper and non-indexed non-dir by upper inode.
696-
* Hash non-indexed dir by upper inode for NFS export.
718+
* Copy up origin (lower) may exist for non-indexed upper, but we must
719+
* not use lower as hash key if this is a broken hardlink.
697720
*/
698721
is_dir = S_ISDIR(realinode->i_mode);
699-
if (is_dir && (indexed || !sb->s_export_op || !ofs->upper_mnt))
700-
origin = lowerdentry;
701-
702-
if (upperdentry || origin) {
703-
struct inode *key = d_inode(origin ?: upperdentry);
722+
if (upperdentry || bylower) {
723+
struct inode *key = d_inode(bylower ? lowerdentry :
724+
upperdentry);
704725
unsigned int nlink = is_dir ? 1 : realinode->i_nlink;
705726

706727
inode = iget5_locked(sb, (unsigned long) key,
@@ -728,6 +749,7 @@ struct inode *ovl_get_inode(struct super_block *sb, struct dentry *upperdentry,
728749
nlink = ovl_get_nlink(lowerdentry, upperdentry, nlink);
729750
set_nlink(inode, nlink);
730751
} else {
752+
/* Lower hardlink that will be broken on copy up */
731753
inode = new_inode(sb);
732754
if (!inode)
733755
goto out_nomem;

0 commit comments

Comments
 (0)