static int ocfs2_readlink(struct dentry *dentry, char __user *buffer, int buflen) { int ret; char *link; struct buffer_head *bh = NULL; struct inode *inode = dentry->d_inode; link = ocfs2_fast_symlink_getlink(inode, &bh); if (IS_ERR(link)) { ret = PTR_ERR(link); goto out; } /* */ ret = vfs_readlink(dentry, buffer, buflen, link); brelse(bh); out: if (ret < 0) mlog_errno(ret); return ret; }
static int ocfs2_readlink(struct dentry *dentry, char __user *buffer, int buflen) { int ret; char *link; struct buffer_head *bh = NULL; struct inode *inode = dentry->d_inode; mlog_entry_void(); link = ocfs2_fast_symlink_getlink(inode, &bh); if (IS_ERR(link)) { ret = PTR_ERR(link); goto out; } /* * Without vfsmount we can't update atime now, * but we will update atime here ultimately. */ ret = vfs_readlink(dentry, buffer, buflen, link); brelse(bh); out: mlog_exit(ret); return ret; }
static void *ocfs2_follow_link(struct dentry *dentry, struct nameidata *nd) { int status; char *link; struct inode *inode = dentry->d_inode; struct page *page = NULL; struct buffer_head *bh = NULL; if (ocfs2_inode_is_fast_symlink(inode)) link = ocfs2_fast_symlink_getlink(inode, &bh); else link = ocfs2_page_getlink(dentry, &page); if (IS_ERR(link)) { status = PTR_ERR(link); mlog_errno(status); goto bail; } status = vfs_follow_link(nd, link); bail: if (page) { kunmap(page); page_cache_release(page); } brelse(bh); return ERR_PTR(status); }
static void *ocfs2_fast_follow_link(struct dentry *dentry, struct nameidata *nd) { int status = 0; int len; char *target, *link = ERR_PTR(-ENOMEM); struct inode *inode = dentry->d_inode; struct buffer_head *bh = NULL; mlog_entry_void(); BUG_ON(!ocfs2_inode_is_fast_symlink(inode)); target = ocfs2_fast_symlink_getlink(inode, &bh); if (IS_ERR(target)) { status = PTR_ERR(target); mlog_errno(status); goto bail; } /* Fast symlinks can't be large */ len = strnlen(target, ocfs2_fast_symlink_chars(inode->i_sb)); link = kzalloc(len + 1, GFP_NOFS); if (!link) { status = -ENOMEM; mlog_errno(status); goto bail; } memcpy(link, target, len); nd_set_link(nd, link); bail: brelse(bh); mlog_exit(status); return status ? ERR_PTR(status) : link; }