diff options
| -rw-r--r-- | fs/gfs2/dir.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/export.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/glock.c | 3 | ||||
| -rw-r--r-- | fs/gfs2/inode.c | 101 | ||||
| -rw-r--r-- | fs/gfs2/inode.h | 5 | ||||
| -rw-r--r-- | fs/gfs2/ops_fstype.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 58 |
7 files changed, 144 insertions, 29 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 25fddc100f18..8295c5b5d4a9 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
| @@ -1475,7 +1475,7 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) | |||
| 1475 | inode = gfs2_inode_lookup(dir->i_sb, | 1475 | inode = gfs2_inode_lookup(dir->i_sb, |
| 1476 | be16_to_cpu(dent->de_type), | 1476 | be16_to_cpu(dent->de_type), |
| 1477 | be64_to_cpu(dent->de_inum.no_addr), | 1477 | be64_to_cpu(dent->de_inum.no_addr), |
| 1478 | be64_to_cpu(dent->de_inum.no_formal_ino), 0); | 1478 | be64_to_cpu(dent->de_inum.no_formal_ino)); |
| 1479 | brelse(bh); | 1479 | brelse(bh); |
| 1480 | return inode; | 1480 | return inode; |
| 1481 | } | 1481 | } |
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c index d15876e9aa26..d81bc7e90e98 100644 --- a/fs/gfs2/export.c +++ b/fs/gfs2/export.c | |||
| @@ -169,7 +169,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, | |||
| 169 | if (error) | 169 | if (error) |
| 170 | goto fail; | 170 | goto fail; |
| 171 | 171 | ||
| 172 | inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0, 0); | 172 | inode = gfs2_inode_lookup(sb, DT_UNKNOWN, inum->no_addr, 0); |
| 173 | if (IS_ERR(inode)) { | 173 | if (IS_ERR(inode)) { |
| 174 | error = PTR_ERR(inode); | 174 | error = PTR_ERR(inode); |
| 175 | goto fail; | 175 | goto fail; |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 454d4b4eb36b..ddcdbf493536 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
| @@ -855,6 +855,9 @@ void gfs2_holder_reinit(unsigned int state, unsigned flags, struct gfs2_holder * | |||
| 855 | gh->gh_flags = flags; | 855 | gh->gh_flags = flags; |
| 856 | gh->gh_iflags = 0; | 856 | gh->gh_iflags = 0; |
| 857 | gh->gh_ip = (unsigned long)__builtin_return_address(0); | 857 | gh->gh_ip = (unsigned long)__builtin_return_address(0); |
| 858 | if (gh->gh_owner_pid) | ||
| 859 | put_pid(gh->gh_owner_pid); | ||
| 860 | gh->gh_owner_pid = get_pid(task_pid(current)); | ||
| 858 | } | 861 | } |
| 859 | 862 | ||
| 860 | /** | 863 | /** |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index b1bf2694fb2b..51d8061fa07a 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
| @@ -158,7 +158,6 @@ void gfs2_set_iop(struct inode *inode) | |||
| 158 | * @sb: The super block | 158 | * @sb: The super block |
| 159 | * @no_addr: The inode number | 159 | * @no_addr: The inode number |
| 160 | * @type: The type of the inode | 160 | * @type: The type of the inode |
| 161 | * @skip_freeing: set this not return an inode if it is currently being freed. | ||
| 162 | * | 161 | * |
| 163 | * Returns: A VFS inode, or an error | 162 | * Returns: A VFS inode, or an error |
| 164 | */ | 163 | */ |
| @@ -166,17 +165,14 @@ void gfs2_set_iop(struct inode *inode) | |||
| 166 | struct inode *gfs2_inode_lookup(struct super_block *sb, | 165 | struct inode *gfs2_inode_lookup(struct super_block *sb, |
| 167 | unsigned int type, | 166 | unsigned int type, |
| 168 | u64 no_addr, | 167 | u64 no_addr, |
| 169 | u64 no_formal_ino, int skip_freeing) | 168 | u64 no_formal_ino) |
| 170 | { | 169 | { |
| 171 | struct inode *inode; | 170 | struct inode *inode; |
| 172 | struct gfs2_inode *ip; | 171 | struct gfs2_inode *ip; |
| 173 | struct gfs2_glock *io_gl; | 172 | struct gfs2_glock *io_gl; |
| 174 | int error; | 173 | int error; |
| 175 | 174 | ||
| 176 | if (skip_freeing) | 175 | inode = gfs2_iget(sb, no_addr); |
| 177 | inode = gfs2_iget_skip(sb, no_addr); | ||
| 178 | else | ||
| 179 | inode = gfs2_iget(sb, no_addr); | ||
| 180 | ip = GFS2_I(inode); | 176 | ip = GFS2_I(inode); |
| 181 | 177 | ||
| 182 | if (!inode) | 178 | if (!inode) |
| @@ -234,13 +230,100 @@ fail_glock: | |||
| 234 | fail_iopen: | 230 | fail_iopen: |
| 235 | gfs2_glock_put(io_gl); | 231 | gfs2_glock_put(io_gl); |
| 236 | fail_put: | 232 | fail_put: |
| 237 | ip->i_gl->gl_object = NULL; | 233 | if (inode->i_state & I_NEW) |
| 234 | ip->i_gl->gl_object = NULL; | ||
| 238 | gfs2_glock_put(ip->i_gl); | 235 | gfs2_glock_put(ip->i_gl); |
| 239 | fail: | 236 | fail: |
| 240 | iget_failed(inode); | 237 | if (inode->i_state & I_NEW) |
| 238 | iget_failed(inode); | ||
| 239 | else | ||
| 240 | iput(inode); | ||
| 241 | return ERR_PTR(error); | 241 | return ERR_PTR(error); |
| 242 | } | 242 | } |
| 243 | 243 | ||
| 244 | /** | ||
| 245 | * gfs2_unlinked_inode_lookup - Lookup an unlinked inode for reclamation | ||
| 246 | * @sb: The super block | ||
| 247 | * no_addr: The inode number | ||
| 248 | * @@inode: A pointer to the inode found, if any | ||
| 249 | * | ||
| 250 | * Returns: 0 and *inode if no errors occurred. If an error occurs, | ||
| 251 | * the resulting *inode may or may not be NULL. | ||
| 252 | */ | ||
| 253 | |||
| 254 | int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, | ||
| 255 | struct inode **inode) | ||
| 256 | { | ||
| 257 | struct gfs2_sbd *sdp; | ||
| 258 | struct gfs2_inode *ip; | ||
| 259 | struct gfs2_glock *io_gl; | ||
| 260 | int error; | ||
| 261 | struct gfs2_holder gh; | ||
| 262 | |||
| 263 | *inode = gfs2_iget_skip(sb, no_addr); | ||
| 264 | |||
| 265 | if (!(*inode)) | ||
| 266 | return -ENOBUFS; | ||
| 267 | |||
| 268 | if (!((*inode)->i_state & I_NEW)) | ||
| 269 | return -ENOBUFS; | ||
| 270 | |||
| 271 | ip = GFS2_I(*inode); | ||
| 272 | sdp = GFS2_SB(*inode); | ||
| 273 | ip->i_no_formal_ino = -1; | ||
| 274 | |||
| 275 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | ||
| 276 | if (unlikely(error)) | ||
| 277 | goto fail; | ||
| 278 | ip->i_gl->gl_object = ip; | ||
| 279 | |||
| 280 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | ||
| 281 | if (unlikely(error)) | ||
| 282 | goto fail_put; | ||
| 283 | |||
| 284 | set_bit(GIF_INVALID, &ip->i_flags); | ||
| 285 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, | ||
| 286 | &ip->i_iopen_gh); | ||
| 287 | if (unlikely(error)) { | ||
| 288 | if (error == GLR_TRYFAILED) | ||
| 289 | error = 0; | ||
| 290 | goto fail_iopen; | ||
| 291 | } | ||
| 292 | ip->i_iopen_gh.gh_gl->gl_object = ip; | ||
| 293 | gfs2_glock_put(io_gl); | ||
| 294 | |||
| 295 | (*inode)->i_mode = DT2IF(DT_UNKNOWN); | ||
| 296 | |||
| 297 | /* | ||
| 298 | * We must read the inode in order to work out its type in | ||
| 299 | * this case. Note that this doesn't happen often as we normally | ||
| 300 | * know the type beforehand. This code path only occurs during | ||
| 301 | * unlinked inode recovery (where it is safe to do this glock, | ||
| 302 | * which is not true in the general case). | ||
| 303 | */ | ||
| 304 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, | ||
| 305 | &gh); | ||
| 306 | if (unlikely(error)) { | ||
| 307 | if (error == GLR_TRYFAILED) | ||
| 308 | error = 0; | ||
| 309 | goto fail_glock; | ||
| 310 | } | ||
| 311 | /* Inode is now uptodate */ | ||
| 312 | gfs2_glock_dq_uninit(&gh); | ||
| 313 | gfs2_set_iop(*inode); | ||
| 314 | |||
| 315 | return 0; | ||
| 316 | fail_glock: | ||
| 317 | gfs2_glock_dq(&ip->i_iopen_gh); | ||
| 318 | fail_iopen: | ||
| 319 | gfs2_glock_put(io_gl); | ||
| 320 | fail_put: | ||
| 321 | ip->i_gl->gl_object = NULL; | ||
| 322 | gfs2_glock_put(ip->i_gl); | ||
| 323 | fail: | ||
| 324 | return error; | ||
| 325 | } | ||
| 326 | |||
| 244 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | 327 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) |
| 245 | { | 328 | { |
| 246 | const struct gfs2_dinode *str = buf; | 329 | const struct gfs2_dinode *str = buf; |
| @@ -862,7 +945,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
| 862 | goto fail_gunlock2; | 945 | goto fail_gunlock2; |
| 863 | 946 | ||
| 864 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr, | 947 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr, |
| 865 | inum.no_formal_ino, 0); | 948 | inum.no_formal_ino); |
| 866 | if (IS_ERR(inode)) | 949 | if (IS_ERR(inode)) |
| 867 | goto fail_gunlock2; | 950 | goto fail_gunlock2; |
| 868 | 951 | ||
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index c341aaf67adb..e161461d4c57 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
| @@ -83,8 +83,9 @@ static inline void gfs2_inum_out(const struct gfs2_inode *ip, | |||
| 83 | 83 | ||
| 84 | extern void gfs2_set_iop(struct inode *inode); | 84 | extern void gfs2_set_iop(struct inode *inode); |
| 85 | extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, | 85 | extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, |
| 86 | u64 no_addr, u64 no_formal_ino, | 86 | u64 no_addr, u64 no_formal_ino); |
| 87 | int skip_freeing); | 87 | extern int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, |
| 88 | struct inode **inode); | ||
| 88 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); | 89 | extern struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr); |
| 89 | 90 | ||
| 90 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); | 91 | extern int gfs2_inode_refresh(struct gfs2_inode *ip); |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index c1309ed1c496..dc35f3470271 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
| @@ -487,7 +487,7 @@ static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr, | |||
| 487 | struct dentry *dentry; | 487 | struct dentry *dentry; |
| 488 | struct inode *inode; | 488 | struct inode *inode; |
| 489 | 489 | ||
| 490 | inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0); | 490 | inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0); |
| 491 | if (IS_ERR(inode)) { | 491 | if (IS_ERR(inode)) { |
| 492 | fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode)); | 492 | fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode)); |
| 493 | return PTR_ERR(inode); | 493 | return PTR_ERR(inode); |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 503b842f3ba2..37391550284f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -948,18 +948,20 @@ static int try_rgrp_fit(struct gfs2_rgrpd *rgd, struct gfs2_alloc *al) | |||
| 948 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes | 948 | * try_rgrp_unlink - Look for any unlinked, allocated, but unused inodes |
| 949 | * @rgd: The rgrp | 949 | * @rgd: The rgrp |
| 950 | * | 950 | * |
| 951 | * Returns: The inode, if one has been found | 951 | * Returns: 0 if no error |
| 952 | * The inode, if one has been found, in inode. | ||
| 952 | */ | 953 | */ |
| 953 | 954 | ||
| 954 | static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, | 955 | static int try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, |
| 955 | u64 skip) | 956 | u64 skip, struct inode **inode) |
| 956 | { | 957 | { |
| 957 | struct inode *inode; | ||
| 958 | u32 goal = 0, block; | 958 | u32 goal = 0, block; |
| 959 | u64 no_addr; | 959 | u64 no_addr; |
| 960 | struct gfs2_sbd *sdp = rgd->rd_sbd; | 960 | struct gfs2_sbd *sdp = rgd->rd_sbd; |
| 961 | unsigned int n; | 961 | unsigned int n; |
| 962 | int error = 0; | ||
| 962 | 963 | ||
| 964 | *inode = NULL; | ||
| 963 | for(;;) { | 965 | for(;;) { |
| 964 | if (goal >= rgd->rd_data) | 966 | if (goal >= rgd->rd_data) |
| 965 | break; | 967 | break; |
| @@ -979,14 +981,14 @@ static struct inode *try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, | |||
| 979 | if (no_addr == skip) | 981 | if (no_addr == skip) |
| 980 | continue; | 982 | continue; |
| 981 | *last_unlinked = no_addr; | 983 | *last_unlinked = no_addr; |
| 982 | inode = gfs2_inode_lookup(rgd->rd_sbd->sd_vfs, DT_UNKNOWN, | 984 | error = gfs2_unlinked_inode_lookup(rgd->rd_sbd->sd_vfs, |
| 983 | no_addr, -1, 1); | 985 | no_addr, inode); |
| 984 | if (!IS_ERR(inode)) | 986 | if (*inode || error) |
| 985 | return inode; | 987 | return error; |
| 986 | } | 988 | } |
| 987 | 989 | ||
| 988 | rgd->rd_flags &= ~GFS2_RDF_CHECK; | 990 | rgd->rd_flags &= ~GFS2_RDF_CHECK; |
| 989 | return NULL; | 991 | return 0; |
| 990 | } | 992 | } |
| 991 | 993 | ||
| 992 | /** | 994 | /** |
| @@ -1096,12 +1098,27 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
| 1096 | case 0: | 1098 | case 0: |
| 1097 | if (try_rgrp_fit(rgd, al)) | 1099 | if (try_rgrp_fit(rgd, al)) |
| 1098 | goto out; | 1100 | goto out; |
| 1099 | if (rgd->rd_flags & GFS2_RDF_CHECK) | 1101 | /* If the rg came in already locked, there's no |
| 1100 | inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | 1102 | way we can recover from a failed try_rgrp_unlink |
| 1103 | because that would require an iput which can only | ||
| 1104 | happen after the rgrp is unlocked. */ | ||
| 1105 | if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) | ||
| 1106 | error = try_rgrp_unlink(rgd, last_unlinked, | ||
| 1107 | ip->i_no_addr, &inode); | ||
| 1101 | if (!rg_locked) | 1108 | if (!rg_locked) |
| 1102 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1109 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
| 1103 | if (inode) | 1110 | if (inode) { |
| 1111 | if (error) { | ||
| 1112 | if (inode->i_state & I_NEW) | ||
| 1113 | iget_failed(inode); | ||
| 1114 | else | ||
| 1115 | iput(inode); | ||
| 1116 | return ERR_PTR(error); | ||
| 1117 | } | ||
| 1104 | return inode; | 1118 | return inode; |
| 1119 | } | ||
| 1120 | if (error) | ||
| 1121 | return ERR_PTR(error); | ||
| 1105 | /* fall through */ | 1122 | /* fall through */ |
| 1106 | case GLR_TRYFAILED: | 1123 | case GLR_TRYFAILED: |
| 1107 | rgd = recent_rgrp_next(rgd); | 1124 | rgd = recent_rgrp_next(rgd); |
| @@ -1130,12 +1147,23 @@ static struct inode *get_local_rgrp(struct gfs2_inode *ip, u64 *last_unlinked) | |||
| 1130 | case 0: | 1147 | case 0: |
| 1131 | if (try_rgrp_fit(rgd, al)) | 1148 | if (try_rgrp_fit(rgd, al)) |
| 1132 | goto out; | 1149 | goto out; |
| 1133 | if (rgd->rd_flags & GFS2_RDF_CHECK) | 1150 | if (!rg_locked && rgd->rd_flags & GFS2_RDF_CHECK) |
| 1134 | inode = try_rgrp_unlink(rgd, last_unlinked, ip->i_no_addr); | 1151 | error = try_rgrp_unlink(rgd, last_unlinked, |
| 1152 | ip->i_no_addr, &inode); | ||
| 1135 | if (!rg_locked) | 1153 | if (!rg_locked) |
| 1136 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 1154 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
| 1137 | if (inode) | 1155 | if (inode) { |
| 1156 | if (error) { | ||
| 1157 | if (inode->i_state & I_NEW) | ||
| 1158 | iget_failed(inode); | ||
| 1159 | else | ||
| 1160 | iput(inode); | ||
| 1161 | return ERR_PTR(error); | ||
| 1162 | } | ||
| 1138 | return inode; | 1163 | return inode; |
| 1164 | } | ||
| 1165 | if (error) | ||
| 1166 | return ERR_PTR(error); | ||
| 1139 | break; | 1167 | break; |
| 1140 | 1168 | ||
| 1141 | case GLR_TRYFAILED: | 1169 | case GLR_TRYFAILED: |
