static void *exofs_follow_link(struct dentry *dentry, struct nameidata *nd) { struct exofs_i_info *oi = exofs_i(dentry->d_inode); nd_set_link(nd, (char *)oi->i_data); return NULL; }
static int exofs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { struct super_block *sb = dir->i_sb; int err = -ENAMETOOLONG; unsigned l = strlen(symname)+1; struct inode *inode; struct exofs_i_info *oi; if (l > sb->s_blocksize) goto out; inode = exofs_new_inode(dir, S_IFLNK | S_IRWXUGO); err = PTR_ERR(inode); if (IS_ERR(inode)) goto out; oi = exofs_i(inode); if (l > sizeof(oi->i_data)) { /* slow symlink */ inode->i_op = &exofs_symlink_inode_operations; inode->i_mapping->a_ops = &exofs_aops; memset(oi->i_data, 0, sizeof(oi->i_data)); err = page_symlink(inode, symname, l); if (err) goto out_fail; } else { /* fast symlink */ inode->i_op = &exofs_fast_symlink_inode_operations; memcpy(oi->i_data, symname, l); inode->i_size = l-1; } mark_inode_dirty(inode); err = exofs_add_nondir(dentry, inode); out: return err; out_fail: inode_dec_link_count(inode); iput(inode); goto out; }
static void exofs_i_callback(struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); kmem_cache_free(exofs_inode_cachep, exofs_i(inode)); }
static void exofs_i_callback(struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); INIT_LIST_HEAD(&inode->i_dentry); kmem_cache_free(exofs_inode_cachep, exofs_i(inode)); }
/* * Remove an inode from the cache */ static void exofs_destroy_inode(struct inode *inode) { kmem_cache_free(exofs_inode_cachep, exofs_i(inode)); }