/* this @nd *IS* still used */ static void unionfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) { struct dentry *parent; char *buf; unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) printk(KERN_ERR "unionfs: put_link failed to revalidate dentry\n"); unionfs_check_dentry(dentry); #if 0 /* XXX: can't run this check b/c this fxn can receive a poisoned 'nd' PTR */ unionfs_check_nd(nd); #endif buf = nd_get_link(nd); if (!IS_ERR(buf)) kfree(buf); unionfs_unlock_dentry(dentry); unionfs_unlock_parent(dentry, parent); unionfs_read_unlock(dentry->d_sb); }
static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd) { char *buf; int len = PAGE_SIZE, err; mm_segment_t old_fs; struct dentry *parent; unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); /* This is freed by the put_link method assuming a successful call. */ buf = kmalloc(len, GFP_KERNEL); if (unlikely(!buf)) { err = -ENOMEM; goto out; } /* read the symlink, and then we will follow it */ old_fs = get_fs(); set_fs(KERNEL_DS); err = __unionfs_readlink(dentry, buf, len); set_fs(old_fs); if (err < 0) { kfree(buf); buf = NULL; goto out; } buf[err] = 0; nd_set_link(nd, buf); err = 0; out: if (err >= 0) { unionfs_check_nd(nd); unionfs_check_dentry(dentry); } unionfs_unlock_dentry(dentry); unionfs_unlock_parent(dentry, parent); unionfs_read_unlock(dentry->d_sb); return ERR_PTR(err); }
/* this @nd *IS* still used */ static void unionfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) { struct dentry *parent; unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD); parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT); unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD); if (unlikely(!__unionfs_d_revalidate(dentry, parent, false))) printk(KERN_ERR "unionfs: put_link failed to revalidate dentry\n"); unionfs_check_dentry(dentry); unionfs_check_nd(nd); kfree(nd_get_link(nd)); unionfs_unlock_dentry(dentry); unionfs_unlock_parent(dentry, parent); unionfs_read_unlock(dentry->d_sb); }