mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 09:43:59 +08:00
ovl: copy up before encoding non-connectable dir file handle
Decoding a merge dir, whose origin's parent is under a redirected lower dir is not always possible. As a simple aproximation, we do not encode lower dir file handles when overlay has multiple lower layers and origin is below the topmost lower layer. We should later relax this condition and copy up only the parent that is under a redirected lower. Signed-off-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
b305e8443f
commit
05e1f11816
@ -34,17 +34,35 @@
|
||||
* --------------------------------
|
||||
* Pure upper | U
|
||||
* Non-indexed upper | U
|
||||
* Indexed upper | L
|
||||
* Non-upper | L
|
||||
* Indexed upper | L (*)
|
||||
* Non-upper | L (*)
|
||||
*
|
||||
* U = upper file handle
|
||||
* L = lower file handle
|
||||
*
|
||||
* (*) Connecting an overlay dir from real lower dentry is not always
|
||||
* possible when there are redirects in lower layers. To mitigate this case,
|
||||
* we copy up the lower dir first and then encode an upper dir file handle.
|
||||
*/
|
||||
static bool ovl_should_encode_origin(struct dentry *dentry)
|
||||
{
|
||||
struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
|
||||
|
||||
if (!ovl_dentry_lower(dentry))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Decoding a merge dir, whose origin's parent is under a redirected
|
||||
* lower dir is not always possible. As a simple aproximation, we do
|
||||
* not encode lower dir file handles when overlay has multiple lower
|
||||
* layers and origin is below the topmost lower layer.
|
||||
*
|
||||
* TODO: copy up only the parent that is under redirected lower.
|
||||
*/
|
||||
if (d_is_dir(dentry) && ofs->upper_mnt &&
|
||||
OVL_E(dentry)->lowerstack[0].layer->idx > 1)
|
||||
return false;
|
||||
|
||||
/* Decoding a non-indexed upper from origin is not implemented */
|
||||
if (ovl_dentry_upper(dentry) &&
|
||||
!ovl_test_flag(OVL_INDEX, d_inode(dentry)))
|
||||
@ -53,16 +71,43 @@ static bool ovl_should_encode_origin(struct dentry *dentry)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ovl_encode_maybe_copy_up(struct dentry *dentry)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (ovl_dentry_upper(dentry))
|
||||
return 0;
|
||||
|
||||
err = ovl_want_write(dentry);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = ovl_copy_up(dentry);
|
||||
|
||||
ovl_drop_write(dentry);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ovl_d_to_fh(struct dentry *dentry, char *buf, int buflen)
|
||||
{
|
||||
struct dentry *upper = ovl_dentry_upper(dentry);
|
||||
struct dentry *upper;
|
||||
struct dentry *origin = ovl_dentry_lower(dentry);
|
||||
struct ovl_fh *fh = NULL;
|
||||
int err;
|
||||
|
||||
if (!ovl_should_encode_origin(dentry))
|
||||
origin = NULL;
|
||||
/*
|
||||
* If we should not encode a lower dir file handle, copy up and encode
|
||||
* an upper dir file handle.
|
||||
*/
|
||||
if (!ovl_should_encode_origin(dentry)) {
|
||||
err = ovl_encode_maybe_copy_up(dentry);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
origin = NULL;
|
||||
}
|
||||
|
||||
upper = ovl_dentry_upper(dentry);
|
||||
err = -EACCES;
|
||||
if (!upper || origin)
|
||||
goto fail;
|
||||
|
Loading…
Reference in New Issue
Block a user