|
19 | 19 | #include <linux/ratelimit.h>
|
20 | 20 | #include "overlayfs.h"
|
21 | 21 |
|
| 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 | + |
22 | 158 | /*
|
23 | 159 | * We only need to encode origin if there is a chance that the same object was
|
24 | 160 | * encoded pre copy up and then we need to stay consistent with the same
|
|
41 | 177 | * L = lower file handle
|
42 | 178 | *
|
43 | 179 | * (*) 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. |
46 | 185 | */
|
47 |
| -static bool ovl_should_encode_origin(struct dentry *dentry) |
| 186 | +static int ovl_check_encode_origin(struct dentry *dentry) |
48 | 187 | {
|
49 | 188 | struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
|
50 | 189 |
|
| 190 | + /* Upper file handle for pure upper */ |
51 | 191 | if (!ovl_dentry_lower(dentry))
|
52 |
| - return false; |
| 192 | + return 0; |
53 | 193 |
|
54 | 194 | /*
|
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. |
59 | 196 | *
|
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. |
61 | 199 | */
|
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 */ |
67 | 200 | if (ovl_dentry_upper(dentry) &&
|
68 | 201 | !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)) |
79 | 202 | return 0;
|
80 | 203 |
|
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); |
86 | 212 |
|
87 |
| - ovl_drop_write(dentry); |
88 |
| - return err; |
| 213 | + /* Lower file handle for indexed and non-upper dir/non-dir */ |
| 214 | + return 1; |
89 | 215 | }
|
90 | 216 |
|
91 | 217 | static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
|
92 | 218 | {
|
93 |
| - struct dentry *origin = ovl_dentry_lower(dentry); |
94 | 219 | struct ovl_fh *fh = NULL;
|
95 |
| - int err; |
| 220 | + int err, enc_lower; |
96 | 221 |
|
97 | 222 | /*
|
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. |
100 | 225 | */
|
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; |
108 | 229 |
|
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); |
111 | 233 | err = PTR_ERR(fh);
|
112 | 234 | if (IS_ERR(fh))
|
113 | 235 | goto fail;
|
@@ -355,8 +477,8 @@ static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
|
355 | 477 | dput(upper);
|
356 | 478 | }
|
357 | 479 |
|
358 |
| - if (!this) |
359 |
| - return NULL; |
| 480 | + if (IS_ERR_OR_NULL(this)) |
| 481 | + return this; |
360 | 482 |
|
361 | 483 | if (WARN_ON(ovl_dentry_real_at(this, layer->idx) != real)) {
|
362 | 484 | dput(this);
|
@@ -498,7 +620,7 @@ static struct dentry *ovl_lookup_real(struct super_block *sb,
|
498 | 620 | if (err == -ECHILD) {
|
499 | 621 | this = ovl_lookup_real_ancestor(sb, real,
|
500 | 622 | layer);
|
501 |
| - err = IS_ERR(this) ? PTR_ERR(this) : 0; |
| 623 | + err = PTR_ERR_OR_ZERO(this); |
502 | 624 | }
|
503 | 625 | if (!err) {
|
504 | 626 | dput(connected);
|
|
0 commit comments