diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/aops.c | 10 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 27 | ||||
-rw-r--r-- | fs/gfs2/ops_inode.c | 18 | ||||
-rw-r--r-- | fs/gfs2/super.c | 43 | ||||
-rw-r--r-- | fs/gfs2/xattr.c | 24 |
5 files changed, 71 insertions, 51 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 5e96cbd8a454..194fe16d8418 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -697,12 +697,12 @@ out: | |||
697 | page_cache_release(page); | 697 | page_cache_release(page); |
698 | 698 | ||
699 | /* | 699 | /* |
700 | * XXX(hch): the call below should probably be replaced with | 700 | * XXX(truncate): the call below should probably be replaced with |
701 | * a call to the gfs2-specific truncate blocks helper to actually | 701 | * a call to the gfs2-specific truncate blocks helper to actually |
702 | * release disk blocks.. | 702 | * release disk blocks.. |
703 | */ | 703 | */ |
704 | if (pos + len > ip->i_inode.i_size) | 704 | if (pos + len > ip->i_inode.i_size) |
705 | simple_setsize(&ip->i_inode, ip->i_inode.i_size); | 705 | truncate_setsize(&ip->i_inode, ip->i_inode.i_size); |
706 | out_endtrans: | 706 | out_endtrans: |
707 | gfs2_trans_end(sdp); | 707 | gfs2_trans_end(sdp); |
708 | out_trans_fail: | 708 | out_trans_fail: |
@@ -1042,9 +1042,9 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | |||
1042 | if (rv != 1) | 1042 | if (rv != 1) |
1043 | goto out; /* dio not valid, fall back to buffered i/o */ | 1043 | goto out; /* dio not valid, fall back to buffered i/o */ |
1044 | 1044 | ||
1045 | rv = blockdev_direct_IO_no_locking(rw, iocb, inode, inode->i_sb->s_bdev, | 1045 | rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov, |
1046 | iov, offset, nr_segs, | 1046 | offset, nr_segs, gfs2_get_block_direct, |
1047 | gfs2_get_block_direct, NULL); | 1047 | NULL, NULL, 0); |
1048 | out: | 1048 | out: |
1049 | gfs2_glock_dq_m(1, &gh); | 1049 | gfs2_glock_dq_m(1, &gh); |
1050 | gfs2_holder_uninit(&gh); | 1050 | gfs2_holder_uninit(&gh); |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index f03afd9c44bc..08140f185a37 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -84,7 +84,7 @@ static int iget_skip_test(struct inode *inode, void *opaque) | |||
84 | struct gfs2_skip_data *data = opaque; | 84 | struct gfs2_skip_data *data = opaque; |
85 | 85 | ||
86 | if (ip->i_no_addr == data->no_addr) { | 86 | if (ip->i_no_addr == data->no_addr) { |
87 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){ | 87 | if (inode->i_state & (I_FREEING|I_WILL_FREE)){ |
88 | data->skipped = 1; | 88 | data->skipped = 1; |
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
@@ -991,18 +991,29 @@ fail: | |||
991 | 991 | ||
992 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 992 | static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
993 | { | 993 | { |
994 | struct inode *inode = &ip->i_inode; | ||
994 | struct buffer_head *dibh; | 995 | struct buffer_head *dibh; |
995 | int error; | 996 | int error; |
996 | 997 | ||
997 | error = gfs2_meta_inode_buffer(ip, &dibh); | 998 | error = gfs2_meta_inode_buffer(ip, &dibh); |
998 | if (!error) { | 999 | if (error) |
999 | error = inode_setattr(&ip->i_inode, attr); | 1000 | return error; |
1000 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1001 | |
1001 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1002 | if ((attr->ia_valid & ATTR_SIZE) && |
1002 | gfs2_dinode_out(ip, dibh->b_data); | 1003 | attr->ia_size != i_size_read(inode)) { |
1003 | brelse(dibh); | 1004 | error = vmtruncate(inode, attr->ia_size); |
1005 | if (error) | ||
1006 | return error; | ||
1004 | } | 1007 | } |
1005 | return error; | 1008 | |
1009 | setattr_copy(inode, attr); | ||
1010 | mark_inode_dirty(inode); | ||
1011 | |||
1012 | gfs2_assert_warn(GFS2_SB(inode), !error); | ||
1013 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
1014 | gfs2_dinode_out(ip, dibh->b_data); | ||
1015 | brelse(dibh); | ||
1016 | return 0; | ||
1006 | } | 1017 | } |
1007 | 1018 | ||
1008 | /** | 1019 | /** |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 98cdd05f3316..1009be2c9737 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -1072,7 +1072,7 @@ int gfs2_permission(struct inode *inode, int mask) | |||
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | /* | 1074 | /* |
1075 | * XXX: should be changed to have proper ordering by opencoding simple_setsize | 1075 | * XXX(truncate): the truncate_setsize calls should be moved to the end. |
1076 | */ | 1076 | */ |
1077 | static int setattr_size(struct inode *inode, struct iattr *attr) | 1077 | static int setattr_size(struct inode *inode, struct iattr *attr) |
1078 | { | 1078 | { |
@@ -1084,10 +1084,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr) | |||
1084 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 1084 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
1085 | if (error) | 1085 | if (error) |
1086 | return error; | 1086 | return error; |
1087 | error = simple_setsize(inode, attr->ia_size); | 1087 | truncate_setsize(inode, attr->ia_size); |
1088 | gfs2_trans_end(sdp); | 1088 | gfs2_trans_end(sdp); |
1089 | if (error) | ||
1090 | return error; | ||
1091 | } | 1089 | } |
1092 | 1090 | ||
1093 | error = gfs2_truncatei(ip, attr->ia_size); | 1091 | error = gfs2_truncatei(ip, attr->ia_size); |
@@ -1136,8 +1134,16 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1136 | if (error) | 1134 | if (error) |
1137 | goto out_end_trans; | 1135 | goto out_end_trans; |
1138 | 1136 | ||
1139 | error = inode_setattr(inode, attr); | 1137 | if ((attr->ia_valid & ATTR_SIZE) && |
1140 | gfs2_assert_warn(sdp, !error); | 1138 | attr->ia_size != i_size_read(inode)) { |
1139 | int error; | ||
1140 | |||
1141 | error = vmtruncate(inode, attr->ia_size); | ||
1142 | gfs2_assert_warn(sdp, !error); | ||
1143 | } | ||
1144 | |||
1145 | setattr_copy(inode, attr); | ||
1146 | mark_inode_dirty(inode); | ||
1141 | 1147 | ||
1142 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1148 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1143 | gfs2_dinode_out(ip, dibh->b_data); | 1149 | gfs2_dinode_out(ip, dibh->b_data); |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 4140811a921c..77cb9f830ee4 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -1188,7 +1188,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1188 | * node for later deallocation. | 1188 | * node for later deallocation. |
1189 | */ | 1189 | */ |
1190 | 1190 | ||
1191 | static void gfs2_drop_inode(struct inode *inode) | 1191 | static int gfs2_drop_inode(struct inode *inode) |
1192 | { | 1192 | { |
1193 | struct gfs2_inode *ip = GFS2_I(inode); | 1193 | struct gfs2_inode *ip = GFS2_I(inode); |
1194 | 1194 | ||
@@ -1197,26 +1197,7 @@ static void gfs2_drop_inode(struct inode *inode) | |||
1197 | if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags)) | 1197 | if (gl && test_bit(GLF_DEMOTE, &gl->gl_flags)) |
1198 | clear_nlink(inode); | 1198 | clear_nlink(inode); |
1199 | } | 1199 | } |
1200 | generic_drop_inode(inode); | 1200 | return generic_drop_inode(inode); |
1201 | } | ||
1202 | |||
1203 | /** | ||
1204 | * gfs2_clear_inode - Deallocate an inode when VFS is done with it | ||
1205 | * @inode: The VFS inode | ||
1206 | * | ||
1207 | */ | ||
1208 | |||
1209 | static void gfs2_clear_inode(struct inode *inode) | ||
1210 | { | ||
1211 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1212 | |||
1213 | ip->i_gl->gl_object = NULL; | ||
1214 | gfs2_glock_put(ip->i_gl); | ||
1215 | ip->i_gl = NULL; | ||
1216 | if (ip->i_iopen_gh.gh_gl) { | ||
1217 | ip->i_iopen_gh.gh_gl->gl_object = NULL; | ||
1218 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | ||
1219 | } | ||
1220 | } | 1201 | } |
1221 | 1202 | ||
1222 | static int is_ancestor(const struct dentry *d1, const struct dentry *d2) | 1203 | static int is_ancestor(const struct dentry *d1, const struct dentry *d2) |
@@ -1344,13 +1325,16 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1344 | * is safe, just less efficient. | 1325 | * is safe, just less efficient. |
1345 | */ | 1326 | */ |
1346 | 1327 | ||
1347 | static void gfs2_delete_inode(struct inode *inode) | 1328 | static void gfs2_evict_inode(struct inode *inode) |
1348 | { | 1329 | { |
1349 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | 1330 | struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; |
1350 | struct gfs2_inode *ip = GFS2_I(inode); | 1331 | struct gfs2_inode *ip = GFS2_I(inode); |
1351 | struct gfs2_holder gh; | 1332 | struct gfs2_holder gh; |
1352 | int error; | 1333 | int error; |
1353 | 1334 | ||
1335 | if (inode->i_nlink) | ||
1336 | goto out; | ||
1337 | |||
1354 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 1338 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
1355 | if (unlikely(error)) { | 1339 | if (unlikely(error)) { |
1356 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 1340 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
@@ -1404,10 +1388,18 @@ out_unlock: | |||
1404 | gfs2_holder_uninit(&ip->i_iopen_gh); | 1388 | gfs2_holder_uninit(&ip->i_iopen_gh); |
1405 | gfs2_glock_dq_uninit(&gh); | 1389 | gfs2_glock_dq_uninit(&gh); |
1406 | if (error && error != GLR_TRYFAILED && error != -EROFS) | 1390 | if (error && error != GLR_TRYFAILED && error != -EROFS) |
1407 | fs_warn(sdp, "gfs2_delete_inode: %d\n", error); | 1391 | fs_warn(sdp, "gfs2_evict_inode: %d\n", error); |
1408 | out: | 1392 | out: |
1409 | truncate_inode_pages(&inode->i_data, 0); | 1393 | truncate_inode_pages(&inode->i_data, 0); |
1410 | clear_inode(inode); | 1394 | end_writeback(inode); |
1395 | |||
1396 | ip->i_gl->gl_object = NULL; | ||
1397 | gfs2_glock_put(ip->i_gl); | ||
1398 | ip->i_gl = NULL; | ||
1399 | if (ip->i_iopen_gh.gh_gl) { | ||
1400 | ip->i_iopen_gh.gh_gl->gl_object = NULL; | ||
1401 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | ||
1402 | } | ||
1411 | } | 1403 | } |
1412 | 1404 | ||
1413 | static struct inode *gfs2_alloc_inode(struct super_block *sb) | 1405 | static struct inode *gfs2_alloc_inode(struct super_block *sb) |
@@ -1431,14 +1423,13 @@ const struct super_operations gfs2_super_ops = { | |||
1431 | .alloc_inode = gfs2_alloc_inode, | 1423 | .alloc_inode = gfs2_alloc_inode, |
1432 | .destroy_inode = gfs2_destroy_inode, | 1424 | .destroy_inode = gfs2_destroy_inode, |
1433 | .write_inode = gfs2_write_inode, | 1425 | .write_inode = gfs2_write_inode, |
1434 | .delete_inode = gfs2_delete_inode, | 1426 | .evict_inode = gfs2_evict_inode, |
1435 | .put_super = gfs2_put_super, | 1427 | .put_super = gfs2_put_super, |
1436 | .sync_fs = gfs2_sync_fs, | 1428 | .sync_fs = gfs2_sync_fs, |
1437 | .freeze_fs = gfs2_freeze, | 1429 | .freeze_fs = gfs2_freeze, |
1438 | .unfreeze_fs = gfs2_unfreeze, | 1430 | .unfreeze_fs = gfs2_unfreeze, |
1439 | .statfs = gfs2_statfs, | 1431 | .statfs = gfs2_statfs, |
1440 | .remount_fs = gfs2_remount_fs, | 1432 | .remount_fs = gfs2_remount_fs, |
1441 | .clear_inode = gfs2_clear_inode, | ||
1442 | .drop_inode = gfs2_drop_inode, | 1433 | .drop_inode = gfs2_drop_inode, |
1443 | .show_options = gfs2_show_options, | 1434 | .show_options = gfs2_show_options, |
1444 | }; | 1435 | }; |
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 82f93da00d1b..776af6eb4bcb 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
@@ -1296,6 +1296,7 @@ fail: | |||
1296 | 1296 | ||
1297 | int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) | 1297 | int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) |
1298 | { | 1298 | { |
1299 | struct inode *inode = &ip->i_inode; | ||
1299 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1300 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1300 | struct gfs2_ea_location el; | 1301 | struct gfs2_ea_location el; |
1301 | struct buffer_head *dibh; | 1302 | struct buffer_head *dibh; |
@@ -1321,14 +1322,25 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) | |||
1321 | return error; | 1322 | return error; |
1322 | 1323 | ||
1323 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1324 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1324 | if (!error) { | 1325 | if (error) |
1325 | error = inode_setattr(&ip->i_inode, attr); | 1326 | goto out_trans_end; |
1326 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1327 | |
1327 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1328 | if ((attr->ia_valid & ATTR_SIZE) && |
1328 | gfs2_dinode_out(ip, dibh->b_data); | 1329 | attr->ia_size != i_size_read(inode)) { |
1329 | brelse(dibh); | 1330 | int error; |
1331 | |||
1332 | error = vmtruncate(inode, attr->ia_size); | ||
1333 | gfs2_assert_warn(GFS2_SB(inode), !error); | ||
1330 | } | 1334 | } |
1331 | 1335 | ||
1336 | setattr_copy(inode, attr); | ||
1337 | mark_inode_dirty(inode); | ||
1338 | |||
1339 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | ||
1340 | gfs2_dinode_out(ip, dibh->b_data); | ||
1341 | brelse(dibh); | ||
1342 | |||
1343 | out_trans_end: | ||
1332 | gfs2_trans_end(sdp); | 1344 | gfs2_trans_end(sdp); |
1333 | return error; | 1345 | return error; |
1334 | } | 1346 | } |