static int smfs_readlink(struct dentry * dentry, char * buffer, int buflen)
{
struct inode *cache_inode = I2CI(dentry->d_inode);
- int rc = 0;
+ struct dentry cache_dentry;
+ int rc = 0;
+ if (!cache_inode)
+ RETURN(-ENOENT);
+
+ smfs_prepare_dentry(&cache_dentry, NULL, &dentry->d_name);
+ d_add(&cache_dentry, cache_inode);
+
if (cache_inode->i_op && cache_inode->i_op->readlink)
- rc = cache_inode->i_op->readlink(dentry, buffer, buflen);
+ rc = cache_inode->i_op->readlink(&cache_dentry, buffer, buflen);
+ smfs_clear_dentry(&cache_dentry);
return rc;
}
static int smfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct inode *cache_inode = I2CI(dentry->d_inode);
+ struct dentry cache_dentry;
int rc = 0;
+ if (!cache_inode)
+ RETURN(-ENOENT);
+
+ smfs_prepare_dentry(&cache_dentry, NULL, &dentry->d_name);
+ d_add(&cache_dentry, cache_inode);
if (cache_inode->i_op && cache_inode->i_op->follow_link)
- rc = cache_inode->i_op->follow_link(dentry, nd);
+ rc = cache_inode->i_op->follow_link(&cache_dentry, nd);
+ smfs_clear_dentry(&cache_dentry);
return rc;
}
struct inode_operations smfs_sym_iops = {
readlink: smfs_readlink,
follow_link: smfs_follow_link,
+ setxattr: smfs_setxattr, /* BKL held */
+ getxattr: smfs_getxattr, /* BKL held */
+ listxattr: smfs_listxattr, /* BKL held */
+ removexattr: smfs_removexattr, /* BKL held */
};
struct file_operations smfs_sym_fops = {