Skip to content

Commit

Permalink
Linux: zhold znode when handing out link to VFS
Browse files Browse the repository at this point in the history
Other linux fs implementations seem to hold a reference to some buffer
which seems to cause the inode to stay in place in tight memory conditions.

Replicate such behavior.

Signed-off-by: Pavel Snajdr <[email protected]>
  • Loading branch information
snajpa committed Oct 30, 2024
1 parent a491855 commit 060fc4e
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions module/os/linux/zfs/zpl_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -700,10 +700,19 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
return (error);
}

struct zpl_link_info {
znode_t *zp;
char *name;
};

static void
zpl_put_link(void *ptr)
{
kmem_free(ptr, MAXPATHLEN);
struct zpl_link_info *zpl_li = ptr;

zrele(zpl_li->zp);
kmem_free(zpl_li->name, MAXPATHLEN);
kmem_free(zpl_li, sizeof (struct zpl_link_info));
}

static int
Expand Down Expand Up @@ -740,7 +749,8 @@ static const char *
zpl_get_link(struct dentry *dentry, struct inode *inode,
struct delayed_call *done)
{
char *link = NULL;
char *link;
struct zpl_link_info *zpl_li;
int error;

if (!dentry)
Expand All @@ -750,7 +760,11 @@ zpl_get_link(struct dentry *dentry, struct inode *inode,
if (error)
return (ERR_PTR(error));

set_delayed_call(done, zpl_put_link, link);
zpl_li = kmem_zalloc(sizeof (struct zpl_link_info), KM_SLEEP);
zpl_li->zp = ITOZ(inode);
zhold(zpl_li->zp);
zpl_li->name = link;
set_delayed_call(done, zpl_put_link, zpl_li);

return (link);
}
Expand Down

0 comments on commit 060fc4e

Please sign in to comment.