Skip to content

Commit 57568af

Browse files
committed
Linux: zhold znode when handing out link to VFS
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]>
1 parent 35b1a81 commit 57568af

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

module/os/linux/zfs/zpl_inode.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -694,10 +694,19 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
694694
return (error);
695695
}
696696

697+
struct zpl_link_info {
698+
znode_t *zp;
699+
char *name;
700+
};
701+
697702
static void
698703
zpl_put_link(void *ptr)
699704
{
700-
kmem_free(ptr, MAXPATHLEN);
705+
struct zpl_link_info *zpl_li = ptr;
706+
707+
zrele(zpl_li->zp);
708+
kmem_free(zpl_li->name, MAXPATHLEN);
709+
kmem_free(zpl_li, sizeof (struct zpl_link_info));
701710
}
702711

703712
static int
@@ -734,7 +743,8 @@ static const char *
734743
zpl_get_link(struct dentry *dentry, struct inode *inode,
735744
struct delayed_call *done)
736745
{
737-
char *link = NULL;
746+
char *link;
747+
struct zpl_link_info *zpl_li;
738748
int error;
739749

740750
if (!dentry)
@@ -744,7 +754,11 @@ zpl_get_link(struct dentry *dentry, struct inode *inode,
744754
if (error)
745755
return (ERR_PTR(error));
746756

747-
set_delayed_call(done, zpl_put_link, link);
757+
zpl_li = kmem_zalloc(sizeof (struct zpl_link_info), KM_SLEEP);
758+
zpl_li->zp = ITOZ(inode);
759+
zhold(zpl_li->zp);
760+
zpl_li->name = link;
761+
set_delayed_call(done, zpl_put_link, zpl_li);
748762

749763
return (link);
750764
}

0 commit comments

Comments
 (0)