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); |
