Skip to content

Commit 060fc4e

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 a491855 commit 060fc4e

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
@@ -700,10 +700,19 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
700700
return (error);
701701
}
702702

703+
struct zpl_link_info {
704+
znode_t *zp;
705+
char *name;
706+
};
707+
703708
static void
704709
zpl_put_link(void *ptr)
705710
{
706-
kmem_free(ptr, MAXPATHLEN);
711+
struct zpl_link_info *zpl_li = ptr;
712+
713+
zrele(zpl_li->zp);
714+
kmem_free(zpl_li->name, MAXPATHLEN);
715+
kmem_free(zpl_li, sizeof (struct zpl_link_info));
707716
}
708717

709718
static int
@@ -740,7 +749,8 @@ static const char *
740749
zpl_get_link(struct dentry *dentry, struct inode *inode,
741750
struct delayed_call *done)
742751
{
743-
char *link = NULL;
752+
char *link;
753+
struct zpl_link_info *zpl_li;
744754
int error;
745755

746756
if (!dentry)
@@ -750,7 +760,11 @@ zpl_get_link(struct dentry *dentry, struct inode *inode,
750760
if (error)
751761
return (ERR_PTR(error));
752762

753-
set_delayed_call(done, zpl_put_link, link);
763+
zpl_li = kmem_zalloc(sizeof (struct zpl_link_info), KM_SLEEP);
764+
zpl_li->zp = ITOZ(inode);
765+
zhold(zpl_li->zp);
766+
zpl_li->name = link;
767+
set_delayed_call(done, zpl_put_link, zpl_li);
754768

755769
return (link);
756770
}

0 commit comments

Comments
 (0)