diff options
Diffstat (limited to 'fs/gfs2/ops_inode.c')
-rw-r--r-- | fs/gfs2/ops_inode.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 911c115b5c6c..291f0c7eaa3b 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -69,7 +69,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
69 | mark_inode_dirty(inode); | 69 | mark_inode_dirty(inode); |
70 | break; | 70 | break; |
71 | } else if (PTR_ERR(inode) != -EEXIST || | 71 | } else if (PTR_ERR(inode) != -EEXIST || |
72 | (nd->intent.open.flags & O_EXCL)) { | 72 | (nd && (nd->intent.open.flags & O_EXCL))) { |
73 | gfs2_holder_uninit(ghs); | 73 | gfs2_holder_uninit(ghs); |
74 | return PTR_ERR(inode); | 74 | return PTR_ERR(inode); |
75 | } | 75 | } |
@@ -278,17 +278,25 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | |||
278 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); | 278 | gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2); |
279 | 279 | ||
280 | 280 | ||
281 | error = gfs2_glock_nq_m(3, ghs); | 281 | error = gfs2_glock_nq(ghs); /* parent */ |
282 | if (error) | 282 | if (error) |
283 | goto out; | 283 | goto out_parent; |
284 | |||
285 | error = gfs2_glock_nq(ghs + 1); /* child */ | ||
286 | if (error) | ||
287 | goto out_child; | ||
288 | |||
289 | error = gfs2_glock_nq(ghs + 2); /* rgrp */ | ||
290 | if (error) | ||
291 | goto out_rgrp; | ||
284 | 292 | ||
285 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); | 293 | error = gfs2_unlink_ok(dip, &dentry->d_name, ip); |
286 | if (error) | 294 | if (error) |
287 | goto out_gunlock; | 295 | goto out_rgrp; |
288 | 296 | ||
289 | error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0); | 297 | error = gfs2_trans_begin(sdp, 2*RES_DINODE + RES_LEAF + RES_RG_BIT, 0); |
290 | if (error) | 298 | if (error) |
291 | goto out_gunlock; | 299 | goto out_rgrp; |
292 | 300 | ||
293 | error = gfs2_dir_del(dip, &dentry->d_name); | 301 | error = gfs2_dir_del(dip, &dentry->d_name); |
294 | if (error) | 302 | if (error) |
@@ -298,12 +306,15 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry) | |||
298 | 306 | ||
299 | out_end_trans: | 307 | out_end_trans: |
300 | gfs2_trans_end(sdp); | 308 | gfs2_trans_end(sdp); |
301 | out_gunlock: | 309 | gfs2_glock_dq(ghs + 2); |
302 | gfs2_glock_dq_m(3, ghs); | 310 | out_rgrp: |
303 | out: | ||
304 | gfs2_holder_uninit(ghs); | ||
305 | gfs2_holder_uninit(ghs + 1); | ||
306 | gfs2_holder_uninit(ghs + 2); | 311 | gfs2_holder_uninit(ghs + 2); |
312 | gfs2_glock_dq(ghs + 1); | ||
313 | out_child: | ||
314 | gfs2_holder_uninit(ghs + 1); | ||
315 | gfs2_glock_dq(ghs); | ||
316 | out_parent: | ||
317 | gfs2_holder_uninit(ghs); | ||
307 | gfs2_glock_dq_uninit(&ri_gh); | 318 | gfs2_glock_dq_uninit(&ri_gh); |
308 | return error; | 319 | return error; |
309 | } | 320 | } |
@@ -894,12 +905,17 @@ static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
894 | static int setattr_size(struct inode *inode, struct iattr *attr) | 905 | static int setattr_size(struct inode *inode, struct iattr *attr) |
895 | { | 906 | { |
896 | struct gfs2_inode *ip = GFS2_I(inode); | 907 | struct gfs2_inode *ip = GFS2_I(inode); |
908 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
897 | int error; | 909 | int error; |
898 | 910 | ||
899 | if (attr->ia_size != ip->i_di.di_size) { | 911 | if (attr->ia_size != ip->i_di.di_size) { |
900 | error = vmtruncate(inode, attr->ia_size); | 912 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
901 | if (error) | 913 | if (error) |
902 | return error; | 914 | return error; |
915 | error = vmtruncate(inode, attr->ia_size); | ||
916 | gfs2_trans_end(sdp); | ||
917 | if (error) | ||
918 | return error; | ||
903 | } | 919 | } |
904 | 920 | ||
905 | error = gfs2_truncatei(ip, attr->ia_size); | 921 | error = gfs2_truncatei(ip, attr->ia_size); |