static int sysv_symlink(struct inode * dir, struct dentry * dentry, const char * symname) { int err = -ENAMETOOLONG; int l = strlen(symname)+1; struct inode * inode; if (l > dir->i_sb->s_blocksize) goto out; inode = sysv_new_inode(dir, S_IFLNK|0777); err = PTR_ERR(inode); if (IS_ERR(inode)) goto out; sysv_set_inode(inode, 0); err = block_symlink(inode, symname, l); if (err) goto out_fail; mark_inode_dirty(inode); err = add_nondir(dentry, inode); out: return err; out_fail: dec_count(inode); iput(inode); goto out; }
static int sysv_symlink(struct inode * dir, struct dentry * dentry, const char * symname) { struct inode * inode; struct sysv_dir_entry * de; struct buffer_head * bh; int err; int l; err = -ENAMETOOLONG; l = strlen(symname)+1; if (l > dir->i_sb->sv_block_size_1) goto out; err = -ENOSPC; if (!(inode = sysv_new_inode(dir))) goto out; inode->i_mode = S_IFLNK | 0777; inode->i_op = &sysv_symlink_inode_operations; inode->i_mapping->a_ops = &sysv_aops; err = block_symlink(inode, symname, l); if (err) goto out_no_entry; mark_inode_dirty(inode); err = sysv_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de); if (err) goto out_no_entry; de->inode = inode->i_ino; mark_buffer_dirty(bh); brelse(bh); d_instantiate(dentry, inode); out: return err; out_no_entry: inode->i_nlink--; mark_inode_dirty(inode); iput(inode); goto out; }