aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/ioctl.c
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-04-06 22:01:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 11:31:17 -0400
commit47420c799830d4676e544dbec56b2a7f787528f5 (patch)
treedd61f6c96942b07f762129c893d9cbbbeff60735 /fs/nilfs2/ioctl.c
parenta2e7d2df82cafb76f76809ddf6e2caa8afe4f75e (diff)
nilfs2: avoid double error caused by nilfs_transaction_end
Pekka Enberg pointed out that double error handlings found after nilfs_transaction_end() can be avoided by separating abort operation: OK, I don't understand this. The only way nilfs_transaction_end() can fail is if we have NILFS_TI_SYNC set and we fail to construct the segment. But why do we want to construct a segment if we don't commit? I guess what I'm asking is why don't we have a separate nilfs_transaction_abort() function that can't fail for the erroneous case to avoid this double error value tracking thing? This does the separation and renames nilfs_transaction_end() to nilfs_transaction_commit() for clarification. Since, some calls of these functions were used just for exclusion control against the segment constructor, they are replaced with semaphore operations. Acked-by: Pekka Enberg <penberg@cs.helsinki.fi> Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nilfs2/ioctl.c')
-rw-r--r--fs/nilfs2/ioctl.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c
index 02e91e167ca2..5ce06a01c7ec 100644
--- a/fs/nilfs2/ioctl.c
+++ b/fs/nilfs2/ioctl.c
@@ -105,7 +105,11 @@ static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
105 nilfs_transaction_begin(inode->i_sb, &ti, 0); 105 nilfs_transaction_begin(inode->i_sb, &ti, 0);
106 ret = nilfs_cpfile_change_cpmode( 106 ret = nilfs_cpfile_change_cpmode(
107 cpfile, cpmode.cm_cno, cpmode.cm_mode); 107 cpfile, cpmode.cm_cno, cpmode.cm_mode);
108 nilfs_transaction_end(inode->i_sb, !ret); 108 if (unlikely(ret < 0)) {
109 nilfs_transaction_abort(inode->i_sb);
110 return ret;
111 }
112 nilfs_transaction_commit(inode->i_sb); /* never fails */
109 return ret; 113 return ret;
110} 114}
111 115
@@ -125,7 +129,11 @@ nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
125 129
126 nilfs_transaction_begin(inode->i_sb, &ti, 0); 130 nilfs_transaction_begin(inode->i_sb, &ti, 0);
127 ret = nilfs_cpfile_delete_checkpoint(cpfile, cno); 131 ret = nilfs_cpfile_delete_checkpoint(cpfile, cno);
128 nilfs_transaction_end(inode->i_sb, !ret); 132 if (unlikely(ret < 0)) {
133 nilfs_transaction_abort(inode->i_sb);
134 return ret;
135 }
136 nilfs_transaction_commit(inode->i_sb); /* never fails */
129 return ret; 137 return ret;
130} 138}
131 139
@@ -142,16 +150,17 @@ static int nilfs_ioctl_get_cpinfo(struct inode *inode, struct file *filp,
142{ 150{
143 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; 151 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
144 struct nilfs_argv argv; 152 struct nilfs_argv argv;
145 struct nilfs_transaction_info ti;
146 int ret; 153 int ret;
147 154
148 if (copy_from_user(&argv, argp, sizeof(argv))) 155 if (copy_from_user(&argv, argp, sizeof(argv)))
149 return -EFAULT; 156 return -EFAULT;
150 157
151 nilfs_transaction_begin(inode->i_sb, &ti, 0); 158 down_read(&nilfs->ns_segctor_sem);
152 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 159 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
153 nilfs_ioctl_do_get_cpinfo); 160 nilfs_ioctl_do_get_cpinfo);
154 nilfs_transaction_end(inode->i_sb, 0); 161 up_read(&nilfs->ns_segctor_sem);
162 if (ret < 0)
163 return ret;
155 164
156 if (copy_to_user(argp, &argv, sizeof(argv))) 165 if (copy_to_user(argp, &argv, sizeof(argv)))
157 ret = -EFAULT; 166 ret = -EFAULT;
@@ -161,14 +170,13 @@ static int nilfs_ioctl_get_cpinfo(struct inode *inode, struct file *filp,
161static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp, 170static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
162 unsigned int cmd, void __user *argp) 171 unsigned int cmd, void __user *argp)
163{ 172{
164 struct inode *cpfile = NILFS_SB(inode->i_sb)->s_nilfs->ns_cpfile; 173 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
165 struct nilfs_cpstat cpstat; 174 struct nilfs_cpstat cpstat;
166 struct nilfs_transaction_info ti;
167 int ret; 175 int ret;
168 176
169 nilfs_transaction_begin(inode->i_sb, &ti, 0); 177 down_read(&nilfs->ns_segctor_sem);
170 ret = nilfs_cpfile_get_stat(cpfile, &cpstat); 178 ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
171 nilfs_transaction_end(inode->i_sb, 0); 179 up_read(&nilfs->ns_segctor_sem);
172 if (ret < 0) 180 if (ret < 0)
173 return ret; 181 return ret;
174 182
@@ -189,16 +197,17 @@ static int nilfs_ioctl_get_suinfo(struct inode *inode, struct file *filp,
189{ 197{
190 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; 198 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
191 struct nilfs_argv argv; 199 struct nilfs_argv argv;
192 struct nilfs_transaction_info ti;
193 int ret; 200 int ret;
194 201
195 if (copy_from_user(&argv, argp, sizeof(argv))) 202 if (copy_from_user(&argv, argp, sizeof(argv)))
196 return -EFAULT; 203 return -EFAULT;
197 204
198 nilfs_transaction_begin(inode->i_sb, &ti, 0); 205 down_read(&nilfs->ns_segctor_sem);
199 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 206 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
200 nilfs_ioctl_do_get_suinfo); 207 nilfs_ioctl_do_get_suinfo);
201 nilfs_transaction_end(inode->i_sb, 0); 208 up_read(&nilfs->ns_segctor_sem);
209 if (ret < 0)
210 return ret;
202 211
203 if (copy_to_user(argp, &argv, sizeof(argv))) 212 if (copy_to_user(argp, &argv, sizeof(argv)))
204 ret = -EFAULT; 213 ret = -EFAULT;
@@ -208,14 +217,13 @@ static int nilfs_ioctl_get_suinfo(struct inode *inode, struct file *filp,
208static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp, 217static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
209 unsigned int cmd, void __user *argp) 218 unsigned int cmd, void __user *argp)
210{ 219{
211 struct inode *sufile = NILFS_SB(inode->i_sb)->s_nilfs->ns_sufile; 220 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
212 struct nilfs_sustat sustat; 221 struct nilfs_sustat sustat;
213 struct nilfs_transaction_info ti;
214 int ret; 222 int ret;
215 223
216 nilfs_transaction_begin(inode->i_sb, &ti, 0); 224 down_read(&nilfs->ns_segctor_sem);
217 ret = nilfs_sufile_get_stat(sufile, &sustat); 225 ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
218 nilfs_transaction_end(inode->i_sb, 0); 226 up_read(&nilfs->ns_segctor_sem);
219 if (ret < 0) 227 if (ret < 0)
220 return ret; 228 return ret;
221 229
@@ -236,16 +244,17 @@ static int nilfs_ioctl_get_vinfo(struct inode *inode, struct file *filp,
236{ 244{
237 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; 245 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
238 struct nilfs_argv argv; 246 struct nilfs_argv argv;
239 struct nilfs_transaction_info ti;
240 int ret; 247 int ret;
241 248
242 if (copy_from_user(&argv, argp, sizeof(argv))) 249 if (copy_from_user(&argv, argp, sizeof(argv)))
243 return -EFAULT; 250 return -EFAULT;
244 251
245 nilfs_transaction_begin(inode->i_sb, &ti, 0); 252 down_read(&nilfs->ns_segctor_sem);
246 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 253 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
247 nilfs_ioctl_do_get_vinfo); 254 nilfs_ioctl_do_get_vinfo);
248 nilfs_transaction_end(inode->i_sb, 0); 255 up_read(&nilfs->ns_segctor_sem);
256 if (ret < 0)
257 return ret;
249 258
250 if (copy_to_user(argp, &argv, sizeof(argv))) 259 if (copy_to_user(argp, &argv, sizeof(argv)))
251 ret = -EFAULT; 260 ret = -EFAULT;
@@ -280,16 +289,17 @@ static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
280{ 289{
281 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; 290 struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
282 struct nilfs_argv argv; 291 struct nilfs_argv argv;
283 struct nilfs_transaction_info ti;
284 int ret; 292 int ret;
285 293
286 if (copy_from_user(&argv, argp, sizeof(argv))) 294 if (copy_from_user(&argv, argp, sizeof(argv)))
287 return -EFAULT; 295 return -EFAULT;
288 296
289 nilfs_transaction_begin(inode->i_sb, &ti, 0); 297 down_read(&nilfs->ns_segctor_sem);
290 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), 298 ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
291 nilfs_ioctl_do_get_bdescs); 299 nilfs_ioctl_do_get_bdescs);
292 nilfs_transaction_end(inode->i_sb, 0); 300 up_read(&nilfs->ns_segctor_sem);
301 if (ret < 0)
302 return ret;
293 303
294 if (copy_to_user(argp, &argv, sizeof(argv))) 304 if (copy_to_user(argp, &argv, sizeof(argv)))
295 ret = -EFAULT; 305 ret = -EFAULT;