aboutsummaryrefslogtreecommitdiffstats
path: root/fs/udf/symlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/udf/symlink.c')
-rw-r--r--fs/udf/symlink.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 6fb7945c1e6e..c3aa6fafd6cf 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -80,11 +80,17 @@ static int udf_symlink_filler(struct file *file, struct page *page)
80 struct inode *inode = page->mapping->host; 80 struct inode *inode = page->mapping->host;
81 struct buffer_head *bh = NULL; 81 struct buffer_head *bh = NULL;
82 unsigned char *symlink; 82 unsigned char *symlink;
83 int err = -EIO; 83 int err;
84 unsigned char *p = kmap(page); 84 unsigned char *p = kmap(page);
85 struct udf_inode_info *iinfo; 85 struct udf_inode_info *iinfo;
86 uint32_t pos; 86 uint32_t pos;
87 87
88 /* We don't support symlinks longer than one block */
89 if (inode->i_size > inode->i_sb->s_blocksize) {
90 err = -ENAMETOOLONG;
91 goto out_unmap;
92 }
93
88 iinfo = UDF_I(inode); 94 iinfo = UDF_I(inode);
89 pos = udf_block_map(inode, 0); 95 pos = udf_block_map(inode, 0);
90 96
@@ -94,8 +100,10 @@ static int udf_symlink_filler(struct file *file, struct page *page)
94 } else { 100 } else {
95 bh = sb_bread(inode->i_sb, pos); 101 bh = sb_bread(inode->i_sb, pos);
96 102
97 if (!bh) 103 if (!bh) {
98 goto out; 104 err = -EIO;
105 goto out_unlock_inode;
106 }
99 107
100 symlink = bh->b_data; 108 symlink = bh->b_data;
101 } 109 }
@@ -109,9 +117,10 @@ static int udf_symlink_filler(struct file *file, struct page *page)
109 unlock_page(page); 117 unlock_page(page);
110 return 0; 118 return 0;
111 119
112out: 120out_unlock_inode:
113 up_read(&iinfo->i_data_sem); 121 up_read(&iinfo->i_data_sem);
114 SetPageError(page); 122 SetPageError(page);
123out_unmap:
115 kunmap(page); 124 kunmap(page);
116 unlock_page(page); 125 unlock_page(page);
117 return err; 126 return err;