aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/incore.h2
-rw-r--r--fs/gfs2/inode.c50
-rw-r--r--fs/gfs2/rgrp.c87
3 files changed, 107 insertions, 32 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index e5069b912d5e..c7c6ec0f17c7 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -95,6 +95,8 @@ struct gfs2_rgrpd {
95 u32 rd_last_alloc_data; 95 u32 rd_last_alloc_data;
96 u32 rd_last_alloc_meta; 96 u32 rd_last_alloc_meta;
97 struct gfs2_sbd *rd_sbd; 97 struct gfs2_sbd *rd_sbd;
98 unsigned long rd_flags;
99#define GFS2_RDF_CHECK 0x0001 /* Need to check for unlinked inodes */
98}; 100};
99 101
100enum gfs2_state_bits { 102enum gfs2_state_bits {
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 87505f7eb745..cacdb0dfe577 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -98,22 +98,8 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned in
98 98
99 if (inode->i_state & I_NEW) { 99 if (inode->i_state & I_NEW) {
100 struct gfs2_sbd *sdp = GFS2_SB(inode); 100 struct gfs2_sbd *sdp = GFS2_SB(inode);
101 umode_t mode = DT2IF(type); 101 umode_t mode;
102 inode->i_private = ip; 102 inode->i_private = ip;
103 inode->i_mode = mode;
104
105 if (S_ISREG(mode)) {
106 inode->i_op = &gfs2_file_iops;
107 inode->i_fop = &gfs2_file_fops;
108 inode->i_mapping->a_ops = &gfs2_file_aops;
109 } else if (S_ISDIR(mode)) {
110 inode->i_op = &gfs2_dir_iops;
111 inode->i_fop = &gfs2_dir_fops;
112 } else if (S_ISLNK(mode)) {
113 inode->i_op = &gfs2_symlink_iops;
114 } else {
115 inode->i_op = &gfs2_dev_iops;
116 }
117 103
118 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); 104 error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
119 if (unlikely(error)) 105 if (unlikely(error))
@@ -130,10 +116,44 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, u64 no_addr, unsigned in
130 goto fail_iopen; 116 goto fail_iopen;
131 117
132 gfs2_glock_put(io_gl); 118 gfs2_glock_put(io_gl);
119
120 /*
121 * We must read the inode in order to work out its type in
122 * this case. Note that this doesn't happen often as we normally
123 * know the type beforehand. This code path only occurs during
124 * unlinked inode recovery (where it is safe to do this glock,
125 * which is not true in the general case).
126 */
127 inode->i_mode = mode = DT2IF(type);
128 if (type == DT_UNKNOWN) {
129 struct gfs2_holder gh;
130 error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
131 if (unlikely(error))
132 goto fail_glock;
133 /* Inode is now uptodate */
134 mode = inode->i_mode;
135 gfs2_glock_dq_uninit(&gh);
136 }
137
138 if (S_ISREG(mode)) {
139 inode->i_op = &gfs2_file_iops;
140 inode->i_fop = &gfs2_file_fops;
141 inode->i_mapping->a_ops = &gfs2_file_aops;
142 } else if (S_ISDIR(mode)) {
143 inode->i_op = &gfs2_dir_iops;
144 inode->i_fop = &gfs2_dir_fops;
145 } else if (S_ISLNK(mode)) {
146 inode->i_op = &gfs2_symlink_iops;
147 } else {
148 inode->i_op = &gfs2_dev_iops;
149 }
150
133 unlock_new_inode(inode); 151 unlock_new_inode(inode);
134 } 152 }
135 153
136 return inode; 154 return inode;
155fail_glock:
156 gfs2_glock_dq(&ip->i_iopen_gh);
137fail_iopen: 157fail_iopen:
138 gfs2_glock_put(io_gl); 158 gfs2_glock_put(io_gl);
139fail_put: 159fail_put:
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 027f6ec5b0d9..fd3fd9074779 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -28,6 +28,7 @@
28#include "ops_file.h" 28#include "ops_file.h"
29#include "util.h" 29#include "util.h"
30#include "log.h" 30#include "log.h"
31#include "inode.h"
31 32
32#define BFITNOENT ((u32)~0) 33#define BFITNOENT ((u32)~0)
33 34
@@ -50,6 +51,9 @@ static const char valid_change[16] = {
50 1, 0, 0, 0 51 1, 0, 0, 0
51}; 52};
52 53
54static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
55 unsigned char old_state, unsigned char new_state);
56
53/** 57/**
54 * gfs2_setbit - Set a bit in the bitmaps 58 * gfs2_setbit - Set a bit in the bitmaps
55 * @buffer: the buffer that holds the bitmaps 59 * @buffer: the buffer that holds the bitmaps
@@ -531,6 +535,7 @@ static int read_rindex_entry(struct gfs2_inode *ip,
531 535
532 rgd->rd_gl->gl_object = rgd; 536 rgd->rd_gl->gl_object = rgd;
533 rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; 537 rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1;
538 rgd->rd_flags |= GFS2_RDF_CHECK;
534 return error; 539 return error;
535} 540}
536 541
@@ -846,6 +851,37 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al)
846} 851}
847 852
848/** 853/**
854 * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes
855 * @rgd: The rgrp
856 *
857 * Returns: The inode, if one has been found
858 */
859
860static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked)
861{
862 struct inode *inode;
863 u32 goal = 0;
864 u64 ino;
865
866 for(;;) {
867 goal = rgblk_search(rgd, goal, GFS2_BLKST_UNLINKED,
868 GFS2_BLKST_UNLINKED);
869 if (goal == 0)
870 return 0;
871 ino = goal + rgd->rd_data0;
872 if (ino <= *last_unlinked)
873 continue;
874 *last_unlinked = ino;
875 inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, ino, DT_UNKNOWN);
876 if (!IS_ERR(inode))
877 return inode;
878 }
879
880 rgd->rd_flags &= ~GFS2_RDF_CHECK;
881 return NULL;
882}
883
884/**
849 * recent_rgrp_first - get first RG from "recent" list 885 * recent_rgrp_first - get first RG from "recent" list
850 * @sdp: The GFS2 superblock 886 * @sdp: The GFS2 superblock
851 * @rglast: address of the rgrp used last 887 * @rglast: address of the rgrp used last
@@ -1006,8 +1042,9 @@ static void forward_rgrp_set(struct gfs2_sbd *sdp, struct gfs2_rgrpd *rgd)
1006 * Returns: errno 1042 * Returns: errno
1007 */ 1043 */
1008 1044
1009static int get_local_rgrp(struct gfs2_inode *ip) 1045static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked)
1010{ 1046{
1047 struct inode *inode = NULL;
1011 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1048 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1012 struct gfs2_rgrpd *rgd, *begin = NULL; 1049 struct gfs2_rgrpd *rgd, *begin = NULL;
1013 struct gfs2_alloc *al = &ip->i_alloc; 1050 struct gfs2_alloc *al = &ip->i_alloc;
@@ -1027,7 +1064,11 @@ static int get_local_rgrp(struct gfs2_inode *ip)
1027 case 0: 1064 case 0:
1028 if (try_rgrp_fit(rgd, al)) 1065 if (try_rgrp_fit(rgd, al))
1029 goto out; 1066 goto out;
1067 if (rgd->rd_flags & GFS2_RDF_CHECK)
1068 inode = try_rgrp_unlink(rgd, last_unlinked);
1030 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1069 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1070 if (inode)
1071 return inode;
1031 rgd = recent_rgrp_next(rgd, 1); 1072 rgd = recent_rgrp_next(rgd, 1);
1032 break; 1073 break;
1033 1074
@@ -1036,7 +1077,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
1036 break; 1077 break;
1037 1078
1038 default: 1079 default:
1039 return error; 1080 return ERR_PTR(error);
1040 } 1081 }
1041 } 1082 }
1042 1083
@@ -1051,7 +1092,11 @@ static int get_local_rgrp(struct gfs2_inode *ip)
1051 case 0: 1092 case 0:
1052 if (try_rgrp_fit(rgd, al)) 1093 if (try_rgrp_fit(rgd, al))
1053 goto out; 1094 goto out;
1095 if (rgd->rd_flags & GFS2_RDF_CHECK)
1096 inode = try_rgrp_unlink(rgd, last_unlinked);
1054 gfs2_glock_dq_uninit(&al->al_rgd_gh); 1097 gfs2_glock_dq_uninit(&al->al_rgd_gh);
1098 if (inode)
1099 return inode;
1055 break; 1100 break;
1056 1101
1057 case GLR_TRYFAILED: 1102 case GLR_TRYFAILED:
@@ -1059,7 +1104,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
1059 break; 1104 break;
1060 1105
1061 default: 1106 default:
1062 return error; 1107 return ERR_PTR(error);
1063 } 1108 }
1064 1109
1065 rgd = gfs2_rgrpd_get_next(rgd); 1110 rgd = gfs2_rgrpd_get_next(rgd);
@@ -1068,7 +1113,7 @@ static int get_local_rgrp(struct gfs2_inode *ip)
1068 1113
1069 if (rgd == begin) { 1114 if (rgd == begin) {
1070 if (++loops >= 3) 1115 if (++loops >= 3)
1071 return -ENOSPC; 1116 return ERR_PTR(-ENOSPC);
1072 if (!skipped) 1117 if (!skipped)
1073 loops++; 1118 loops++;
1074 flags = 0; 1119 flags = 0;
@@ -1088,7 +1133,7 @@ out:
1088 forward_rgrp_set(sdp, rgd); 1133 forward_rgrp_set(sdp, rgd);
1089 } 1134 }
1090 1135
1091 return 0; 1136 return NULL;
1092} 1137}
1093 1138
1094/** 1139/**
@@ -1102,11 +1147,14 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
1102{ 1147{
1103 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); 1148 struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
1104 struct gfs2_alloc *al = &ip->i_alloc; 1149 struct gfs2_alloc *al = &ip->i_alloc;
1150 struct inode *inode;
1105 int error = 0; 1151 int error = 0;
1152 u64 last_unlinked = 0;
1106 1153
1107 if (gfs2_assert_warn(sdp, al->al_requested)) 1154 if (gfs2_assert_warn(sdp, al->al_requested))
1108 return -EINVAL; 1155 return -EINVAL;
1109 1156
1157try_again:
1110 /* We need to hold the rindex unless the inode we're using is 1158 /* We need to hold the rindex unless the inode we're using is
1111 the rindex itself, in which case it's already held. */ 1159 the rindex itself, in which case it's already held. */
1112 if (ip != GFS2_I(sdp->sd_rindex)) 1160 if (ip != GFS2_I(sdp->sd_rindex))
@@ -1117,11 +1165,15 @@ int gfs2_inplace_reserve_i(struct gfs2_inode *ip, char *file, unsigned int line)
1117 if (error) 1165 if (error)
1118 return error; 1166 return error;
1119 1167
1120 error = get_local_rgrp(ip); 1168 inode = get_local_rgrp(ip, &last_unlinked);
1121 if (error) { 1169 if (inode) {
1122 if (ip != GFS2_I(sdp->sd_rindex)) 1170 if (ip != GFS2_I(sdp->sd_rindex))
1123 gfs2_glock_dq_uninit(&al->al_ri_gh); 1171 gfs2_glock_dq_uninit(&al->al_ri_gh);
1124 return error; 1172 if (IS_ERR(inode))
1173 return PTR_ERR(inode);
1174 iput(inode);
1175 gfs2_log_flush(sdp, NULL);
1176 goto try_again;
1125 } 1177 }
1126 1178
1127 al->al_file = file; 1179 al->al_file = file;
@@ -1209,7 +1261,7 @@ unsigned char gfs2_get_block_type(struct gfs2_rgrpd *rgd, u64 block)
1209 */ 1261 */
1210 1262
1211static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, 1263static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
1212 unsigned char old_state, unsigned char new_state) 1264 unsigned char old_state, unsigned char new_state)
1213{ 1265{
1214 struct gfs2_bitmap *bi = NULL; 1266 struct gfs2_bitmap *bi = NULL;
1215 u32 length = rgd->rd_length; 1267 u32 length = rgd->rd_length;
@@ -1250,17 +1302,18 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
1250 goal = 0; 1302 goal = 0;
1251 } 1303 }
1252 1304
1253 if (gfs2_assert_withdraw(rgd->rd_sbd, x <= length)) 1305 if (old_state != new_state) {
1254 blk = 0; 1306 gfs2_assert_withdraw(rgd->rd_sbd, blk != BFITNOENT);
1255 1307
1256 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); 1308 gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
1257 gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, 1309 gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset,
1258 bi->bi_len, blk, new_state);
1259 if (bi->bi_clone)
1260 gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset,
1261 bi->bi_len, blk, new_state); 1310 bi->bi_len, blk, new_state);
1311 if (bi->bi_clone)
1312 gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset,
1313 bi->bi_len, blk, new_state);
1314 }
1262 1315
1263 return bi->bi_start * GFS2_NBBY + blk; 1316 return (blk == BFITNOENT) ? 0 : (bi->bi_start * GFS2_NBBY) + blk;
1264} 1317}
1265 1318
1266/** 1319/**