/** * relayfs destroy_inode() implementation */ static void relayfs_destroy_inode(struct inode *inode) { if (RELAYFS_I(inode)->buf) relay_destroy_buf(RELAYFS_I(inode)->buf); kmem_cache_free(relayfs_inode_cachep, RELAYFS_I(inode)); }
static struct inode *relayfs_get_inode(struct super_block *sb, int mode, struct rchan *chan) { struct rchan_buf *buf = NULL; struct inode *inode; if (S_ISREG(mode)) { BUG_ON(!chan); buf = relay_create_buf(chan); if (!buf) return NULL; } inode = new_inode(sb); if (!inode) { relay_destroy_buf(buf); return NULL; } inode->i_mode = mode; inode->i_uid = 0; inode->i_gid = 0; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_mapping->backing_dev_info = &relayfs_backing_dev_info; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; switch (mode & S_IFMT) { case S_IFREG: inode->i_fop = &relayfs_file_operations; RELAYFS_I(inode)->buf = buf; break; case S_IFDIR: inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ inode->i_nlink++; break; default: break; } return inode; }
/** * relay_remove_buf - remove a channel buffer * * Removes the file from the fileystem, which also frees the * rchan_buf_struct and the channel buffer. Should only be called from * kref_put(). */ void relay_remove_buf(struct kref *kref) { struct rchan_buf *buf = container_of(kref, struct rchan_buf, kref); buf->chan->cb->remove_buf_file(buf->dentry); relay_destroy_buf(buf); }