Skip to content

Commit

Permalink
ovl: create ovl_need_index() helper
Browse files Browse the repository at this point in the history
The helper determines which lower file needs to be indexed
on copy up and before nlink changes.

For index=on, the helper evaluates to true for lower hardlinks.

Signed-off-by: Amir Goldstein <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
  • Loading branch information
amir73il authored and Miklos Szeredi committed Jan 24, 2018
1 parent 9ee60ce commit 24b33ee
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 9 deletions.
6 changes: 1 addition & 5 deletions fs/overlayfs/copy_up.c
Original file line number Diff line number Diff line change
Expand Up @@ -536,11 +536,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
{
int err;
struct ovl_fs *ofs = c->dentry->d_sb->s_fs_info;
bool indexed = false;

if (ovl_indexdir(c->dentry->d_sb) && !S_ISDIR(c->stat.mode) &&
c->stat.nlink > 1)
indexed = true;
bool indexed = ovl_need_index(c->dentry);

if (S_ISDIR(c->stat.mode) || c->stat.nlink == 1 || indexed)
c->origin = true;
Expand Down
1 change: 1 addition & 0 deletions fs/overlayfs/overlayfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ void ovl_clear_flag(unsigned long flag, struct inode *inode);
bool ovl_test_flag(unsigned long flag, struct inode *inode);
bool ovl_inuse_trylock(struct dentry *dentry);
void ovl_inuse_unlock(struct dentry *dentry);
bool ovl_need_index(struct dentry *dentry);
int ovl_nlink_start(struct dentry *dentry, bool *locked);
void ovl_nlink_end(struct dentry *dentry, bool locked);
int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
Expand Down
24 changes: 20 additions & 4 deletions fs/overlayfs/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,23 @@ void ovl_inuse_unlock(struct dentry *dentry)
}
}

/*
* Does this overlay dentry need to be indexed on copy up?
*/
bool ovl_need_index(struct dentry *dentry)
{
struct dentry *lower = ovl_dentry_lower(dentry);

if (!lower || !ovl_indexdir(dentry->d_sb))
return false;

/* Index only lower hardlinks on copy up */
if (!d_is_dir(lower) && d_inode(lower)->i_nlink > 1)
return true;

return false;
}

/* Caller must hold OVL_I(inode)->lock */
static void ovl_cleanup_index(struct dentry *dentry)
{
Expand Down Expand Up @@ -533,20 +550,19 @@ int ovl_nlink_start(struct dentry *dentry, bool *locked)

/*
* With inodes index is enabled, we store the union overlay nlink
* in an xattr on the index inode. When whiting out lower hardlinks
* in an xattr on the index inode. When whiting out an indexed lower,
* we need to decrement the overlay persistent nlink, but before the
* first copy up, we have no upper index inode to store the xattr.
*
* As a workaround, before whiteout/rename over of a lower hardlink,
* As a workaround, before whiteout/rename over an indexed lower,
* copy up to create the upper index. Creating the upper index will
* initialize the overlay nlink, so it could be dropped if unlink
* or rename succeeds.
*
* TODO: implement metadata only index copy up when called with
* ovl_copy_up_flags(dentry, O_PATH).
*/
if (ovl_indexdir(dentry->d_sb) && !ovl_dentry_has_upper_alias(dentry) &&
d_inode(ovl_dentry_lower(dentry))->i_nlink > 1) {
if (ovl_need_index(dentry) && !ovl_dentry_has_upper_alias(dentry)) {
err = ovl_copy_up(dentry);
if (err)
return err;
Expand Down

0 comments on commit 24b33ee

Please sign in to comment.