diff options
Diffstat (limited to 'fs/gfs2')
-rw-r--r-- | fs/gfs2/acl.c | 81 | ||||
-rw-r--r-- | fs/gfs2/acl.h | 2 | ||||
-rw-r--r-- | fs/gfs2/aops.c | 3 | ||||
-rw-r--r-- | fs/gfs2/bmap.c | 14 | ||||
-rw-r--r-- | fs/gfs2/dir.c | 221 | ||||
-rw-r--r-- | fs/gfs2/dir.h | 1 | ||||
-rw-r--r-- | fs/gfs2/file.c | 23 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 39 | ||||
-rw-r--r-- | fs/gfs2/glock.h | 6 | ||||
-rw-r--r-- | fs/gfs2/glops.c | 15 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 5 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 35 | ||||
-rw-r--r-- | fs/gfs2/inode.h | 2 | ||||
-rw-r--r-- | fs/gfs2/log.c | 1 | ||||
-rw-r--r-- | fs/gfs2/main.c | 3 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 4 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 52 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 4 | ||||
-rw-r--r-- | fs/gfs2/super.c | 38 | ||||
-rw-r--r-- | fs/gfs2/sys.c | 7 |
20 files changed, 271 insertions, 285 deletions
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index cbc07155b1a0..34501b64bc47 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -67,39 +67,12 @@ static struct posix_acl *gfs2_acl_get(struct gfs2_inode *ip, int type) | |||
67 | return acl; | 67 | return acl; |
68 | } | 68 | } |
69 | 69 | ||
70 | /** | 70 | struct posix_acl *gfs2_get_acl(struct inode *inode, int type) |
71 | * gfs2_check_acl - Check an ACL to see if we're allowed to do something | ||
72 | * @inode: the file we want to do something to | ||
73 | * @mask: what we want to do | ||
74 | * | ||
75 | * Returns: errno | ||
76 | */ | ||
77 | |||
78 | int gfs2_check_acl(struct inode *inode, int mask, unsigned int flags) | ||
79 | { | 71 | { |
80 | struct posix_acl *acl; | 72 | return gfs2_acl_get(GFS2_I(inode), type); |
81 | int error; | ||
82 | |||
83 | if (flags & IPERM_FLAG_RCU) { | ||
84 | if (!negative_cached_acl(inode, ACL_TYPE_ACCESS)) | ||
85 | return -ECHILD; | ||
86 | return -EAGAIN; | ||
87 | } | ||
88 | |||
89 | acl = gfs2_acl_get(GFS2_I(inode), ACL_TYPE_ACCESS); | ||
90 | if (IS_ERR(acl)) | ||
91 | return PTR_ERR(acl); | ||
92 | |||
93 | if (acl) { | ||
94 | error = posix_acl_permission(inode, acl, mask); | ||
95 | posix_acl_release(acl); | ||
96 | return error; | ||
97 | } | ||
98 | |||
99 | return -EAGAIN; | ||
100 | } | 73 | } |
101 | 74 | ||
102 | static int gfs2_set_mode(struct inode *inode, mode_t mode) | 75 | static int gfs2_set_mode(struct inode *inode, umode_t mode) |
103 | { | 76 | { |
104 | int error = 0; | 77 | int error = 0; |
105 | 78 | ||
@@ -143,8 +116,8 @@ out: | |||
143 | int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) | 116 | int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) |
144 | { | 117 | { |
145 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 118 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
146 | struct posix_acl *acl, *clone; | 119 | struct posix_acl *acl; |
147 | mode_t mode = inode->i_mode; | 120 | umode_t mode = inode->i_mode; |
148 | int error = 0; | 121 | int error = 0; |
149 | 122 | ||
150 | if (!sdp->sd_args.ar_posix_acl) | 123 | if (!sdp->sd_args.ar_posix_acl) |
@@ -168,16 +141,10 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode) | |||
168 | goto out; | 141 | goto out; |
169 | } | 142 | } |
170 | 143 | ||
171 | clone = posix_acl_clone(acl, GFP_NOFS); | 144 | error = posix_acl_create(&acl, GFP_NOFS, &mode); |
172 | error = -ENOMEM; | ||
173 | if (!clone) | ||
174 | goto out; | ||
175 | posix_acl_release(acl); | ||
176 | acl = clone; | ||
177 | |||
178 | error = posix_acl_create_masq(acl, &mode); | ||
179 | if (error < 0) | 145 | if (error < 0) |
180 | goto out; | 146 | return error; |
147 | |||
181 | if (error == 0) | 148 | if (error == 0) |
182 | goto munge; | 149 | goto munge; |
183 | 150 | ||
@@ -193,7 +160,7 @@ out: | |||
193 | 160 | ||
194 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | 161 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) |
195 | { | 162 | { |
196 | struct posix_acl *acl, *clone; | 163 | struct posix_acl *acl; |
197 | char *data; | 164 | char *data; |
198 | unsigned int len; | 165 | unsigned int len; |
199 | int error; | 166 | int error; |
@@ -204,25 +171,19 @@ int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr) | |||
204 | if (!acl) | 171 | if (!acl) |
205 | return gfs2_setattr_simple(ip, attr); | 172 | return gfs2_setattr_simple(ip, attr); |
206 | 173 | ||
207 | clone = posix_acl_clone(acl, GFP_NOFS); | 174 | error = posix_acl_chmod(&acl, GFP_NOFS, attr->ia_mode); |
175 | if (error) | ||
176 | return error; | ||
177 | |||
178 | len = posix_acl_to_xattr(acl, NULL, 0); | ||
179 | data = kmalloc(len, GFP_NOFS); | ||
208 | error = -ENOMEM; | 180 | error = -ENOMEM; |
209 | if (!clone) | 181 | if (data == NULL) |
210 | goto out; | 182 | goto out; |
211 | posix_acl_release(acl); | 183 | posix_acl_to_xattr(acl, data, len); |
212 | acl = clone; | 184 | error = gfs2_xattr_acl_chmod(ip, attr, data); |
213 | 185 | kfree(data); | |
214 | error = posix_acl_chmod_masq(acl, attr->ia_mode); | 186 | set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); |
215 | if (!error) { | ||
216 | len = posix_acl_to_xattr(acl, NULL, 0); | ||
217 | data = kmalloc(len, GFP_NOFS); | ||
218 | error = -ENOMEM; | ||
219 | if (data == NULL) | ||
220 | goto out; | ||
221 | posix_acl_to_xattr(acl, data, len); | ||
222 | error = gfs2_xattr_acl_chmod(ip, attr, data); | ||
223 | kfree(data); | ||
224 | set_cached_acl(&ip->i_inode, ACL_TYPE_ACCESS, acl); | ||
225 | } | ||
226 | 187 | ||
227 | out: | 188 | out: |
228 | posix_acl_release(acl); | 189 | posix_acl_release(acl); |
@@ -315,7 +276,7 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name, | |||
315 | goto out_release; | 276 | goto out_release; |
316 | 277 | ||
317 | if (type == ACL_TYPE_ACCESS) { | 278 | if (type == ACL_TYPE_ACCESS) { |
318 | mode_t mode = inode->i_mode; | 279 | umode_t mode = inode->i_mode; |
319 | error = posix_acl_equiv_mode(acl, &mode); | 280 | error = posix_acl_equiv_mode(acl, &mode); |
320 | 281 | ||
321 | if (error <= 0) { | 282 | if (error <= 0) { |
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index a93907c8159b..0da38dc7efec 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #define GFS2_POSIX_ACL_DEFAULT "posix_acl_default" | 16 | #define GFS2_POSIX_ACL_DEFAULT "posix_acl_default" |
17 | #define GFS2_ACL_MAX_ENTRIES 25 | 17 | #define GFS2_ACL_MAX_ENTRIES 25 |
18 | 18 | ||
19 | extern int gfs2_check_acl(struct inode *inode, int mask, unsigned int); | 19 | extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type); |
20 | extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); | 20 | extern int gfs2_acl_create(struct gfs2_inode *dip, struct inode *inode); |
21 | extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); | 21 | extern int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); |
22 | extern const struct xattr_handler gfs2_xattr_system_handler; | 22 | extern const struct xattr_handler gfs2_xattr_system_handler; |
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 802ac5eeba28..f9fbbe96c222 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -1069,6 +1069,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1069 | return 0; | 1069 | return 0; |
1070 | 1070 | ||
1071 | gfs2_log_lock(sdp); | 1071 | gfs2_log_lock(sdp); |
1072 | spin_lock(&sdp->sd_ail_lock); | ||
1072 | head = bh = page_buffers(page); | 1073 | head = bh = page_buffers(page); |
1073 | do { | 1074 | do { |
1074 | if (atomic_read(&bh->b_count)) | 1075 | if (atomic_read(&bh->b_count)) |
@@ -1080,6 +1081,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1080 | goto not_possible; | 1081 | goto not_possible; |
1081 | bh = bh->b_this_page; | 1082 | bh = bh->b_this_page; |
1082 | } while(bh != head); | 1083 | } while(bh != head); |
1084 | spin_unlock(&sdp->sd_ail_lock); | ||
1083 | gfs2_log_unlock(sdp); | 1085 | gfs2_log_unlock(sdp); |
1084 | 1086 | ||
1085 | head = bh = page_buffers(page); | 1087 | head = bh = page_buffers(page); |
@@ -1112,6 +1114,7 @@ not_possible: /* Should never happen */ | |||
1112 | WARN_ON(buffer_dirty(bh)); | 1114 | WARN_ON(buffer_dirty(bh)); |
1113 | WARN_ON(buffer_pinned(bh)); | 1115 | WARN_ON(buffer_pinned(bh)); |
1114 | cannot_release: | 1116 | cannot_release: |
1117 | spin_unlock(&sdp->sd_ail_lock); | ||
1115 | gfs2_log_unlock(sdp); | 1118 | gfs2_log_unlock(sdp); |
1116 | return 0; | 1119 | return 0; |
1117 | } | 1120 | } |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index e65493a8ac00..7878c473ae62 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -854,11 +854,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
854 | blen++; | 854 | blen++; |
855 | else { | 855 | else { |
856 | if (bstart) { | 856 | if (bstart) { |
857 | if (metadata) | 857 | __gfs2_free_blocks(ip, bstart, blen, metadata); |
858 | __gfs2_free_meta(ip, bstart, blen); | ||
859 | else | ||
860 | __gfs2_free_data(ip, bstart, blen); | ||
861 | |||
862 | btotal += blen; | 858 | btotal += blen; |
863 | } | 859 | } |
864 | 860 | ||
@@ -870,11 +866,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
870 | gfs2_add_inode_blocks(&ip->i_inode, -1); | 866 | gfs2_add_inode_blocks(&ip->i_inode, -1); |
871 | } | 867 | } |
872 | if (bstart) { | 868 | if (bstart) { |
873 | if (metadata) | 869 | __gfs2_free_blocks(ip, bstart, blen, metadata); |
874 | __gfs2_free_meta(ip, bstart, blen); | ||
875 | else | ||
876 | __gfs2_free_data(ip, bstart, blen); | ||
877 | |||
878 | btotal += blen; | 870 | btotal += blen; |
879 | } | 871 | } |
880 | 872 | ||
@@ -1224,6 +1216,8 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize) | |||
1224 | if (ret) | 1216 | if (ret) |
1225 | return ret; | 1217 | return ret; |
1226 | 1218 | ||
1219 | inode_dio_wait(inode); | ||
1220 | |||
1227 | oldsize = inode->i_size; | 1221 | oldsize = inode->i_size; |
1228 | if (newsize >= oldsize) | 1222 | if (newsize >= oldsize) |
1229 | return do_grow(inode, newsize); | 1223 | return do_grow(inode, newsize); |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 091ee4779538..1cc2f8ec52a2 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -339,6 +339,67 @@ fail: | |||
339 | return (copied) ? copied : error; | 339 | return (copied) ? copied : error; |
340 | } | 340 | } |
341 | 341 | ||
342 | /** | ||
343 | * gfs2_dir_get_hash_table - Get pointer to the dir hash table | ||
344 | * @ip: The inode in question | ||
345 | * | ||
346 | * Returns: The hash table or an error | ||
347 | */ | ||
348 | |||
349 | static __be64 *gfs2_dir_get_hash_table(struct gfs2_inode *ip) | ||
350 | { | ||
351 | struct inode *inode = &ip->i_inode; | ||
352 | int ret; | ||
353 | u32 hsize; | ||
354 | __be64 *hc; | ||
355 | |||
356 | BUG_ON(!(ip->i_diskflags & GFS2_DIF_EXHASH)); | ||
357 | |||
358 | hc = ip->i_hash_cache; | ||
359 | if (hc) | ||
360 | return hc; | ||
361 | |||
362 | hsize = 1 << ip->i_depth; | ||
363 | hsize *= sizeof(__be64); | ||
364 | if (hsize != i_size_read(&ip->i_inode)) { | ||
365 | gfs2_consist_inode(ip); | ||
366 | return ERR_PTR(-EIO); | ||
367 | } | ||
368 | |||
369 | hc = kmalloc(hsize, GFP_NOFS); | ||
370 | ret = -ENOMEM; | ||
371 | if (hc == NULL) | ||
372 | return ERR_PTR(-ENOMEM); | ||
373 | |||
374 | ret = gfs2_dir_read_data(ip, (char *)hc, 0, hsize, 1); | ||
375 | if (ret < 0) { | ||
376 | kfree(hc); | ||
377 | return ERR_PTR(ret); | ||
378 | } | ||
379 | |||
380 | spin_lock(&inode->i_lock); | ||
381 | if (ip->i_hash_cache) | ||
382 | kfree(hc); | ||
383 | else | ||
384 | ip->i_hash_cache = hc; | ||
385 | spin_unlock(&inode->i_lock); | ||
386 | |||
387 | return ip->i_hash_cache; | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * gfs2_dir_hash_inval - Invalidate dir hash | ||
392 | * @ip: The directory inode | ||
393 | * | ||
394 | * Must be called with an exclusive glock, or during glock invalidation. | ||
395 | */ | ||
396 | void gfs2_dir_hash_inval(struct gfs2_inode *ip) | ||
397 | { | ||
398 | __be64 *hc = ip->i_hash_cache; | ||
399 | ip->i_hash_cache = NULL; | ||
400 | kfree(hc); | ||
401 | } | ||
402 | |||
342 | static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent) | 403 | static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent) |
343 | { | 404 | { |
344 | return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0; | 405 | return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0; |
@@ -686,17 +747,12 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, | |||
686 | static int get_leaf_nr(struct gfs2_inode *dip, u32 index, | 747 | static int get_leaf_nr(struct gfs2_inode *dip, u32 index, |
687 | u64 *leaf_out) | 748 | u64 *leaf_out) |
688 | { | 749 | { |
689 | __be64 leaf_no; | 750 | __be64 *hash; |
690 | int error; | ||
691 | |||
692 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, | ||
693 | index * sizeof(__be64), | ||
694 | sizeof(__be64), 0); | ||
695 | if (error != sizeof(u64)) | ||
696 | return (error < 0) ? error : -EIO; | ||
697 | |||
698 | *leaf_out = be64_to_cpu(leaf_no); | ||
699 | 751 | ||
752 | hash = gfs2_dir_get_hash_table(dip); | ||
753 | if (IS_ERR(hash)) | ||
754 | return PTR_ERR(hash); | ||
755 | *leaf_out = be64_to_cpu(*(hash + index)); | ||
700 | return 0; | 756 | return 0; |
701 | } | 757 | } |
702 | 758 | ||
@@ -966,6 +1022,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
966 | for (x = 0; x < half_len; x++) | 1022 | for (x = 0; x < half_len; x++) |
967 | lp[x] = cpu_to_be64(bn); | 1023 | lp[x] = cpu_to_be64(bn); |
968 | 1024 | ||
1025 | gfs2_dir_hash_inval(dip); | ||
1026 | |||
969 | error = gfs2_dir_write_data(dip, (char *)lp, start * sizeof(u64), | 1027 | error = gfs2_dir_write_data(dip, (char *)lp, start * sizeof(u64), |
970 | half_len * sizeof(u64)); | 1028 | half_len * sizeof(u64)); |
971 | if (error != half_len * sizeof(u64)) { | 1029 | if (error != half_len * sizeof(u64)) { |
@@ -1052,70 +1110,54 @@ fail_brelse: | |||
1052 | 1110 | ||
1053 | static int dir_double_exhash(struct gfs2_inode *dip) | 1111 | static int dir_double_exhash(struct gfs2_inode *dip) |
1054 | { | 1112 | { |
1055 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
1056 | struct buffer_head *dibh; | 1113 | struct buffer_head *dibh; |
1057 | u32 hsize; | 1114 | u32 hsize; |
1058 | u64 *buf; | 1115 | u32 hsize_bytes; |
1059 | u64 *from, *to; | 1116 | __be64 *hc; |
1060 | u64 block; | 1117 | __be64 *hc2, *h; |
1061 | u64 disksize = i_size_read(&dip->i_inode); | ||
1062 | int x; | 1118 | int x; |
1063 | int error = 0; | 1119 | int error = 0; |
1064 | 1120 | ||
1065 | hsize = 1 << dip->i_depth; | 1121 | hsize = 1 << dip->i_depth; |
1066 | if (hsize * sizeof(u64) != disksize) { | 1122 | hsize_bytes = hsize * sizeof(__be64); |
1067 | gfs2_consist_inode(dip); | ||
1068 | return -EIO; | ||
1069 | } | ||
1070 | 1123 | ||
1071 | /* Allocate both the "from" and "to" buffers in one big chunk */ | 1124 | hc = gfs2_dir_get_hash_table(dip); |
1125 | if (IS_ERR(hc)) | ||
1126 | return PTR_ERR(hc); | ||
1072 | 1127 | ||
1073 | buf = kcalloc(3, sdp->sd_hash_bsize, GFP_NOFS); | 1128 | h = hc2 = kmalloc(hsize_bytes * 2, GFP_NOFS); |
1074 | if (!buf) | 1129 | if (!hc2) |
1075 | return -ENOMEM; | 1130 | return -ENOMEM; |
1076 | 1131 | ||
1077 | for (block = disksize >> sdp->sd_hash_bsize_shift; block--;) { | 1132 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1078 | error = gfs2_dir_read_data(dip, (char *)buf, | 1133 | if (error) |
1079 | block * sdp->sd_hash_bsize, | 1134 | goto out_kfree; |
1080 | sdp->sd_hash_bsize, 1); | ||
1081 | if (error != sdp->sd_hash_bsize) { | ||
1082 | if (error >= 0) | ||
1083 | error = -EIO; | ||
1084 | goto fail; | ||
1085 | } | ||
1086 | |||
1087 | from = buf; | ||
1088 | to = (u64 *)((char *)buf + sdp->sd_hash_bsize); | ||
1089 | |||
1090 | for (x = sdp->sd_hash_ptrs; x--; from++) { | ||
1091 | *to++ = *from; /* No endianess worries */ | ||
1092 | *to++ = *from; | ||
1093 | } | ||
1094 | 1135 | ||
1095 | error = gfs2_dir_write_data(dip, | 1136 | for (x = 0; x < hsize; x++) { |
1096 | (char *)buf + sdp->sd_hash_bsize, | 1137 | *h++ = *hc; |
1097 | block * sdp->sd_sb.sb_bsize, | 1138 | *h++ = *hc; |
1098 | sdp->sd_sb.sb_bsize); | 1139 | hc++; |
1099 | if (error != sdp->sd_sb.sb_bsize) { | ||
1100 | if (error >= 0) | ||
1101 | error = -EIO; | ||
1102 | goto fail; | ||
1103 | } | ||
1104 | } | 1140 | } |
1105 | 1141 | ||
1106 | kfree(buf); | 1142 | error = gfs2_dir_write_data(dip, (char *)hc2, 0, hsize_bytes * 2); |
1107 | 1143 | if (error != (hsize_bytes * 2)) | |
1108 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1144 | goto fail; |
1109 | if (!gfs2_assert_withdraw(sdp, !error)) { | ||
1110 | dip->i_depth++; | ||
1111 | gfs2_dinode_out(dip, dibh->b_data); | ||
1112 | brelse(dibh); | ||
1113 | } | ||
1114 | 1145 | ||
1115 | return error; | 1146 | gfs2_dir_hash_inval(dip); |
1147 | dip->i_hash_cache = hc2; | ||
1148 | dip->i_depth++; | ||
1149 | gfs2_dinode_out(dip, dibh->b_data); | ||
1150 | brelse(dibh); | ||
1151 | return 0; | ||
1116 | 1152 | ||
1117 | fail: | 1153 | fail: |
1118 | kfree(buf); | 1154 | /* Replace original hash table & size */ |
1155 | gfs2_dir_write_data(dip, (char *)hc, 0, hsize_bytes); | ||
1156 | i_size_write(&dip->i_inode, hsize_bytes); | ||
1157 | gfs2_dinode_out(dip, dibh->b_data); | ||
1158 | brelse(dibh); | ||
1159 | out_kfree: | ||
1160 | kfree(hc2); | ||
1119 | return error; | 1161 | return error; |
1120 | } | 1162 | } |
1121 | 1163 | ||
@@ -1348,6 +1390,7 @@ out: | |||
1348 | return error; | 1390 | return error; |
1349 | } | 1391 | } |
1350 | 1392 | ||
1393 | |||
1351 | /** | 1394 | /** |
1352 | * dir_e_read - Reads the entries from a directory into a filldir buffer | 1395 | * dir_e_read - Reads the entries from a directory into a filldir buffer |
1353 | * @dip: dinode pointer | 1396 | * @dip: dinode pointer |
@@ -1362,9 +1405,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1362 | filldir_t filldir) | 1405 | filldir_t filldir) |
1363 | { | 1406 | { |
1364 | struct gfs2_inode *dip = GFS2_I(inode); | 1407 | struct gfs2_inode *dip = GFS2_I(inode); |
1365 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
1366 | u32 hsize, len = 0; | 1408 | u32 hsize, len = 0; |
1367 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | ||
1368 | u32 hash, index; | 1409 | u32 hash, index; |
1369 | __be64 *lp; | 1410 | __be64 *lp; |
1370 | int copied = 0; | 1411 | int copied = 0; |
@@ -1372,37 +1413,17 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1372 | unsigned depth = 0; | 1413 | unsigned depth = 0; |
1373 | 1414 | ||
1374 | hsize = 1 << dip->i_depth; | 1415 | hsize = 1 << dip->i_depth; |
1375 | if (hsize * sizeof(u64) != i_size_read(inode)) { | ||
1376 | gfs2_consist_inode(dip); | ||
1377 | return -EIO; | ||
1378 | } | ||
1379 | |||
1380 | hash = gfs2_dir_offset2hash(*offset); | 1416 | hash = gfs2_dir_offset2hash(*offset); |
1381 | index = hash >> (32 - dip->i_depth); | 1417 | index = hash >> (32 - dip->i_depth); |
1382 | 1418 | ||
1383 | lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS); | 1419 | lp = gfs2_dir_get_hash_table(dip); |
1384 | if (!lp) | 1420 | if (IS_ERR(lp)) |
1385 | return -ENOMEM; | 1421 | return PTR_ERR(lp); |
1386 | 1422 | ||
1387 | while (index < hsize) { | 1423 | while (index < hsize) { |
1388 | lp_offset = index & (sdp->sd_hash_ptrs - 1); | ||
1389 | ht_offset = index - lp_offset; | ||
1390 | |||
1391 | if (ht_offset_cur != ht_offset) { | ||
1392 | error = gfs2_dir_read_data(dip, (char *)lp, | ||
1393 | ht_offset * sizeof(__be64), | ||
1394 | sdp->sd_hash_bsize, 1); | ||
1395 | if (error != sdp->sd_hash_bsize) { | ||
1396 | if (error >= 0) | ||
1397 | error = -EIO; | ||
1398 | goto out; | ||
1399 | } | ||
1400 | ht_offset_cur = ht_offset; | ||
1401 | } | ||
1402 | |||
1403 | error = gfs2_dir_read_leaf(inode, offset, opaque, filldir, | 1424 | error = gfs2_dir_read_leaf(inode, offset, opaque, filldir, |
1404 | &copied, &depth, | 1425 | &copied, &depth, |
1405 | be64_to_cpu(lp[lp_offset])); | 1426 | be64_to_cpu(lp[index])); |
1406 | if (error) | 1427 | if (error) |
1407 | break; | 1428 | break; |
1408 | 1429 | ||
@@ -1410,8 +1431,6 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1410 | index = (index & ~(len - 1)) + len; | 1431 | index = (index & ~(len - 1)) + len; |
1411 | } | 1432 | } |
1412 | 1433 | ||
1413 | out: | ||
1414 | kfree(lp); | ||
1415 | if (error > 0) | 1434 | if (error > 0) |
1416 | error = 0; | 1435 | error = 0; |
1417 | return error; | 1436 | return error; |
@@ -1914,43 +1933,22 @@ out: | |||
1914 | 1933 | ||
1915 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip) | 1934 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip) |
1916 | { | 1935 | { |
1917 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
1918 | struct buffer_head *bh; | 1936 | struct buffer_head *bh; |
1919 | struct gfs2_leaf *leaf; | 1937 | struct gfs2_leaf *leaf; |
1920 | u32 hsize, len; | 1938 | u32 hsize, len; |
1921 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | ||
1922 | u32 index = 0, next_index; | 1939 | u32 index = 0, next_index; |
1923 | __be64 *lp; | 1940 | __be64 *lp; |
1924 | u64 leaf_no; | 1941 | u64 leaf_no; |
1925 | int error = 0, last; | 1942 | int error = 0, last; |
1926 | 1943 | ||
1927 | hsize = 1 << dip->i_depth; | 1944 | hsize = 1 << dip->i_depth; |
1928 | if (hsize * sizeof(u64) != i_size_read(&dip->i_inode)) { | ||
1929 | gfs2_consist_inode(dip); | ||
1930 | return -EIO; | ||
1931 | } | ||
1932 | 1945 | ||
1933 | lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS); | 1946 | lp = gfs2_dir_get_hash_table(dip); |
1934 | if (!lp) | 1947 | if (IS_ERR(lp)) |
1935 | return -ENOMEM; | 1948 | return PTR_ERR(lp); |
1936 | 1949 | ||
1937 | while (index < hsize) { | 1950 | while (index < hsize) { |
1938 | lp_offset = index & (sdp->sd_hash_ptrs - 1); | 1951 | leaf_no = be64_to_cpu(lp[index]); |
1939 | ht_offset = index - lp_offset; | ||
1940 | |||
1941 | if (ht_offset_cur != ht_offset) { | ||
1942 | error = gfs2_dir_read_data(dip, (char *)lp, | ||
1943 | ht_offset * sizeof(__be64), | ||
1944 | sdp->sd_hash_bsize, 1); | ||
1945 | if (error != sdp->sd_hash_bsize) { | ||
1946 | if (error >= 0) | ||
1947 | error = -EIO; | ||
1948 | goto out; | ||
1949 | } | ||
1950 | ht_offset_cur = ht_offset; | ||
1951 | } | ||
1952 | |||
1953 | leaf_no = be64_to_cpu(lp[lp_offset]); | ||
1954 | if (leaf_no) { | 1952 | if (leaf_no) { |
1955 | error = get_leaf(dip, leaf_no, &bh); | 1953 | error = get_leaf(dip, leaf_no, &bh); |
1956 | if (error) | 1954 | if (error) |
@@ -1976,7 +1974,6 @@ int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip) | |||
1976 | } | 1974 | } |
1977 | 1975 | ||
1978 | out: | 1976 | out: |
1979 | kfree(lp); | ||
1980 | 1977 | ||
1981 | return error; | 1978 | return error; |
1982 | } | 1979 | } |
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index e686af11becd..ff5772fbf024 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h | |||
@@ -35,6 +35,7 @@ extern int gfs2_diradd_alloc_required(struct inode *dir, | |||
35 | const struct qstr *filename); | 35 | const struct qstr *filename); |
36 | extern int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block, | 36 | extern int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block, |
37 | struct buffer_head **bhp); | 37 | struct buffer_head **bhp); |
38 | extern void gfs2_dir_hash_inval(struct gfs2_inode *ip); | ||
38 | 39 | ||
39 | static inline u32 gfs2_disk_hash(const char *data, int len) | 40 | static inline u32 gfs2_disk_hash(const char *data, int len) |
40 | { | 41 | { |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index a9f5cbe45cd9..edeb9e802903 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -174,7 +174,9 @@ void gfs2_set_inode_flags(struct inode *inode) | |||
174 | struct gfs2_inode *ip = GFS2_I(inode); | 174 | struct gfs2_inode *ip = GFS2_I(inode); |
175 | unsigned int flags = inode->i_flags; | 175 | unsigned int flags = inode->i_flags; |
176 | 176 | ||
177 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | 177 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_NOSEC); |
178 | if ((ip->i_eattr == 0) && !is_sxid(inode->i_mode)) | ||
179 | inode->i_flags |= S_NOSEC; | ||
178 | if (ip->i_diskflags & GFS2_DIF_IMMUTABLE) | 180 | if (ip->i_diskflags & GFS2_DIF_IMMUTABLE) |
179 | flags |= S_IMMUTABLE; | 181 | flags |= S_IMMUTABLE; |
180 | if (ip->i_diskflags & GFS2_DIF_APPENDONLY) | 182 | if (ip->i_diskflags & GFS2_DIF_APPENDONLY) |
@@ -243,7 +245,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
243 | !capable(CAP_LINUX_IMMUTABLE)) | 245 | !capable(CAP_LINUX_IMMUTABLE)) |
244 | goto out; | 246 | goto out; |
245 | if (!IS_IMMUTABLE(inode)) { | 247 | if (!IS_IMMUTABLE(inode)) { |
246 | error = gfs2_permission(inode, MAY_WRITE, 0); | 248 | error = gfs2_permission(inode, MAY_WRITE); |
247 | if (error) | 249 | if (error) |
248 | goto out; | 250 | goto out; |
249 | } | 251 | } |
@@ -544,7 +546,9 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
544 | 546 | ||
545 | /** | 547 | /** |
546 | * gfs2_fsync - sync the dirty data for a file (across the cluster) | 548 | * gfs2_fsync - sync the dirty data for a file (across the cluster) |
547 | * @file: the file that points to the dentry (we ignore this) | 549 | * @file: the file that points to the dentry |
550 | * @start: the start position in the file to sync | ||
551 | * @end: the end position in the file to sync | ||
548 | * @datasync: set if we can ignore timestamp changes | 552 | * @datasync: set if we can ignore timestamp changes |
549 | * | 553 | * |
550 | * The VFS will flush data for us. We only need to worry | 554 | * The VFS will flush data for us. We only need to worry |
@@ -553,23 +557,32 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
553 | * Returns: errno | 557 | * Returns: errno |
554 | */ | 558 | */ |
555 | 559 | ||
556 | static int gfs2_fsync(struct file *file, int datasync) | 560 | static int gfs2_fsync(struct file *file, loff_t start, loff_t end, |
561 | int datasync) | ||
557 | { | 562 | { |
558 | struct inode *inode = file->f_mapping->host; | 563 | struct inode *inode = file->f_mapping->host; |
559 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | 564 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); |
560 | struct gfs2_inode *ip = GFS2_I(inode); | 565 | struct gfs2_inode *ip = GFS2_I(inode); |
561 | int ret; | 566 | int ret; |
562 | 567 | ||
568 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | ||
569 | if (ret) | ||
570 | return ret; | ||
571 | mutex_lock(&inode->i_mutex); | ||
572 | |||
563 | if (datasync) | 573 | if (datasync) |
564 | sync_state &= ~I_DIRTY_SYNC; | 574 | sync_state &= ~I_DIRTY_SYNC; |
565 | 575 | ||
566 | if (sync_state) { | 576 | if (sync_state) { |
567 | ret = sync_inode_metadata(inode, 1); | 577 | ret = sync_inode_metadata(inode, 1); |
568 | if (ret) | 578 | if (ret) { |
579 | mutex_unlock(&inode->i_mutex); | ||
569 | return ret; | 580 | return ret; |
581 | } | ||
570 | gfs2_ail_flush(ip->i_gl); | 582 | gfs2_ail_flush(ip->i_gl); |
571 | } | 583 | } |
572 | 584 | ||
585 | mutex_unlock(&inode->i_mutex); | ||
573 | return 0; | 586 | return 0; |
574 | } | 587 | } |
575 | 588 | ||
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 1c1336e7b3b2..88e8a23d0026 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -409,6 +409,10 @@ static void state_change(struct gfs2_glock *gl, unsigned int new_state) | |||
409 | if (held1 && held2 && list_empty(&gl->gl_holders)) | 409 | if (held1 && held2 && list_empty(&gl->gl_holders)) |
410 | clear_bit(GLF_QUEUED, &gl->gl_flags); | 410 | clear_bit(GLF_QUEUED, &gl->gl_flags); |
411 | 411 | ||
412 | if (new_state != gl->gl_target) | ||
413 | /* shorten our minimum hold time */ | ||
414 | gl->gl_hold_time = max(gl->gl_hold_time - GL_GLOCK_HOLD_DECR, | ||
415 | GL_GLOCK_MIN_HOLD); | ||
412 | gl->gl_state = new_state; | 416 | gl->gl_state = new_state; |
413 | gl->gl_tchange = jiffies; | 417 | gl->gl_tchange = jiffies; |
414 | } | 418 | } |
@@ -668,7 +672,7 @@ static void glock_work_func(struct work_struct *work) | |||
668 | gl->gl_demote_state != LM_ST_EXCLUSIVE) { | 672 | gl->gl_demote_state != LM_ST_EXCLUSIVE) { |
669 | unsigned long holdtime, now = jiffies; | 673 | unsigned long holdtime, now = jiffies; |
670 | 674 | ||
671 | holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; | 675 | holdtime = gl->gl_tchange + gl->gl_hold_time; |
672 | if (time_before(now, holdtime)) | 676 | if (time_before(now, holdtime)) |
673 | delay = holdtime - now; | 677 | delay = holdtime - now; |
674 | 678 | ||
@@ -679,9 +683,14 @@ static void glock_work_func(struct work_struct *work) | |||
679 | } | 683 | } |
680 | run_queue(gl, 0); | 684 | run_queue(gl, 0); |
681 | spin_unlock(&gl->gl_spin); | 685 | spin_unlock(&gl->gl_spin); |
682 | if (!delay || | 686 | if (!delay) |
683 | queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | ||
684 | gfs2_glock_put(gl); | 687 | gfs2_glock_put(gl); |
688 | else { | ||
689 | if (gl->gl_name.ln_type != LM_TYPE_INODE) | ||
690 | delay = 0; | ||
691 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | ||
692 | gfs2_glock_put(gl); | ||
693 | } | ||
685 | if (drop_ref) | 694 | if (drop_ref) |
686 | gfs2_glock_put(gl); | 695 | gfs2_glock_put(gl); |
687 | } | 696 | } |
@@ -743,6 +752,7 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
743 | gl->gl_tchange = jiffies; | 752 | gl->gl_tchange = jiffies; |
744 | gl->gl_object = NULL; | 753 | gl->gl_object = NULL; |
745 | gl->gl_sbd = sdp; | 754 | gl->gl_sbd = sdp; |
755 | gl->gl_hold_time = GL_GLOCK_DFT_HOLD; | ||
746 | INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); | 756 | INIT_DELAYED_WORK(&gl->gl_work, glock_work_func); |
747 | INIT_WORK(&gl->gl_delete, delete_work_func); | 757 | INIT_WORK(&gl->gl_delete, delete_work_func); |
748 | 758 | ||
@@ -855,8 +865,15 @@ static int gfs2_glock_demote_wait(void *word) | |||
855 | 865 | ||
856 | static void wait_on_holder(struct gfs2_holder *gh) | 866 | static void wait_on_holder(struct gfs2_holder *gh) |
857 | { | 867 | { |
868 | unsigned long time1 = jiffies; | ||
869 | |||
858 | might_sleep(); | 870 | might_sleep(); |
859 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, gfs2_glock_holder_wait, TASK_UNINTERRUPTIBLE); | 871 | wait_on_bit(&gh->gh_iflags, HIF_WAIT, gfs2_glock_holder_wait, TASK_UNINTERRUPTIBLE); |
872 | if (time_after(jiffies, time1 + HZ)) /* have we waited > a second? */ | ||
873 | /* Lengthen the minimum hold time. */ | ||
874 | gh->gh_gl->gl_hold_time = min(gh->gh_gl->gl_hold_time + | ||
875 | GL_GLOCK_HOLD_INCR, | ||
876 | GL_GLOCK_MAX_HOLD); | ||
860 | } | 877 | } |
861 | 878 | ||
862 | static void wait_on_demote(struct gfs2_glock *gl) | 879 | static void wait_on_demote(struct gfs2_glock *gl) |
@@ -1093,8 +1110,9 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
1093 | 1110 | ||
1094 | gfs2_glock_hold(gl); | 1111 | gfs2_glock_hold(gl); |
1095 | if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && | 1112 | if (test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) && |
1096 | !test_bit(GLF_DEMOTE, &gl->gl_flags)) | 1113 | !test_bit(GLF_DEMOTE, &gl->gl_flags) && |
1097 | delay = gl->gl_ops->go_min_hold_time; | 1114 | gl->gl_name.ln_type == LM_TYPE_INODE) |
1115 | delay = gl->gl_hold_time; | ||
1098 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | 1116 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) |
1099 | gfs2_glock_put(gl); | 1117 | gfs2_glock_put(gl); |
1100 | } | 1118 | } |
@@ -1273,12 +1291,13 @@ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state) | |||
1273 | unsigned long now = jiffies; | 1291 | unsigned long now = jiffies; |
1274 | 1292 | ||
1275 | gfs2_glock_hold(gl); | 1293 | gfs2_glock_hold(gl); |
1276 | holdtime = gl->gl_tchange + gl->gl_ops->go_min_hold_time; | 1294 | holdtime = gl->gl_tchange + gl->gl_hold_time; |
1277 | if (test_bit(GLF_QUEUED, &gl->gl_flags)) { | 1295 | if (test_bit(GLF_QUEUED, &gl->gl_flags) && |
1296 | gl->gl_name.ln_type == LM_TYPE_INODE) { | ||
1278 | if (time_before(now, holdtime)) | 1297 | if (time_before(now, holdtime)) |
1279 | delay = holdtime - now; | 1298 | delay = holdtime - now; |
1280 | if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags)) | 1299 | if (test_bit(GLF_REPLY_PENDING, &gl->gl_flags)) |
1281 | delay = gl->gl_ops->go_min_hold_time; | 1300 | delay = gl->gl_hold_time; |
1282 | } | 1301 | } |
1283 | 1302 | ||
1284 | spin_lock(&gl->gl_spin); | 1303 | spin_lock(&gl->gl_spin); |
@@ -1667,7 +1686,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl) | |||
1667 | dtime *= 1000000/HZ; /* demote time in uSec */ | 1686 | dtime *= 1000000/HZ; /* demote time in uSec */ |
1668 | if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) | 1687 | if (!test_bit(GLF_DEMOTE, &gl->gl_flags)) |
1669 | dtime = 0; | 1688 | dtime = 0; |
1670 | gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d v:%d r:%d\n", | 1689 | gfs2_print_dbg(seq, "G: s:%s n:%u/%llx f:%s t:%s d:%s/%llu a:%d v:%d r:%d m:%ld\n", |
1671 | state2str(gl->gl_state), | 1690 | state2str(gl->gl_state), |
1672 | gl->gl_name.ln_type, | 1691 | gl->gl_name.ln_type, |
1673 | (unsigned long long)gl->gl_name.ln_number, | 1692 | (unsigned long long)gl->gl_name.ln_number, |
@@ -1676,7 +1695,7 @@ static int __dump_glock(struct seq_file *seq, const struct gfs2_glock *gl) | |||
1676 | state2str(gl->gl_demote_state), dtime, | 1695 | state2str(gl->gl_demote_state), dtime, |
1677 | atomic_read(&gl->gl_ail_count), | 1696 | atomic_read(&gl->gl_ail_count), |
1678 | atomic_read(&gl->gl_revokes), | 1697 | atomic_read(&gl->gl_revokes), |
1679 | atomic_read(&gl->gl_ref)); | 1698 | atomic_read(&gl->gl_ref), gl->gl_hold_time); |
1680 | 1699 | ||
1681 | list_for_each_entry(gh, &gl->gl_holders, gh_list) { | 1700 | list_for_each_entry(gh, &gl->gl_holders, gh_list) { |
1682 | error = dump_holder(seq, gh); | 1701 | error = dump_holder(seq, gh); |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 6b2f757b9281..66707118af25 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -113,6 +113,12 @@ enum { | |||
113 | 113 | ||
114 | #define GLR_TRYFAILED 13 | 114 | #define GLR_TRYFAILED 13 |
115 | 115 | ||
116 | #define GL_GLOCK_MAX_HOLD (long)(HZ / 5) | ||
117 | #define GL_GLOCK_DFT_HOLD (long)(HZ / 5) | ||
118 | #define GL_GLOCK_MIN_HOLD (long)(10) | ||
119 | #define GL_GLOCK_HOLD_INCR (long)(HZ / 20) | ||
120 | #define GL_GLOCK_HOLD_DECR (long)(HZ / 40) | ||
121 | |||
116 | struct lm_lockops { | 122 | struct lm_lockops { |
117 | const char *lm_proto_name; | 123 | const char *lm_proto_name; |
118 | int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname); | 124 | int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname); |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 8ef70f464731..da21ecaafcc2 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "rgrp.h" | 26 | #include "rgrp.h" |
27 | #include "util.h" | 27 | #include "util.h" |
28 | #include "trans.h" | 28 | #include "trans.h" |
29 | #include "dir.h" | ||
29 | 30 | ||
30 | /** | 31 | /** |
31 | * __gfs2_ail_flush - remove all buffers for a given lock from the AIL | 32 | * __gfs2_ail_flush - remove all buffers for a given lock from the AIL |
@@ -47,10 +48,10 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl) | |||
47 | bd_ail_gl_list); | 48 | bd_ail_gl_list); |
48 | bh = bd->bd_bh; | 49 | bh = bd->bd_bh; |
49 | gfs2_remove_from_ail(bd); | 50 | gfs2_remove_from_ail(bd); |
50 | spin_unlock(&sdp->sd_ail_lock); | ||
51 | |||
52 | bd->bd_bh = NULL; | 51 | bd->bd_bh = NULL; |
53 | bh->b_private = NULL; | 52 | bh->b_private = NULL; |
53 | spin_unlock(&sdp->sd_ail_lock); | ||
54 | |||
54 | bd->bd_blkno = bh->b_blocknr; | 55 | bd->bd_blkno = bh->b_blocknr; |
55 | gfs2_log_lock(sdp); | 56 | gfs2_log_lock(sdp); |
56 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); | 57 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); |
@@ -218,11 +219,14 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) | |||
218 | if (ip) { | 219 | if (ip) { |
219 | set_bit(GIF_INVALID, &ip->i_flags); | 220 | set_bit(GIF_INVALID, &ip->i_flags); |
220 | forget_all_cached_acls(&ip->i_inode); | 221 | forget_all_cached_acls(&ip->i_inode); |
222 | gfs2_dir_hash_inval(ip); | ||
221 | } | 223 | } |
222 | } | 224 | } |
223 | 225 | ||
224 | if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) | 226 | if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) { |
227 | gfs2_log_flush(gl->gl_sbd, NULL); | ||
225 | gl->gl_sbd->sd_rindex_uptodate = 0; | 228 | gl->gl_sbd->sd_rindex_uptodate = 0; |
229 | } | ||
226 | if (ip && S_ISREG(ip->i_inode.i_mode)) | 230 | if (ip && S_ISREG(ip->i_inode.i_mode)) |
227 | truncate_inode_pages(ip->i_inode.i_mapping, 0); | 231 | truncate_inode_pages(ip->i_inode.i_mapping, 0); |
228 | } | 232 | } |
@@ -314,6 +318,8 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
314 | ip->i_generation = be64_to_cpu(str->di_generation); | 318 | ip->i_generation = be64_to_cpu(str->di_generation); |
315 | 319 | ||
316 | ip->i_diskflags = be32_to_cpu(str->di_flags); | 320 | ip->i_diskflags = be32_to_cpu(str->di_flags); |
321 | ip->i_eattr = be64_to_cpu(str->di_eattr); | ||
322 | /* i_diskflags and i_eattr must be set before gfs2_set_inode_flags() */ | ||
317 | gfs2_set_inode_flags(&ip->i_inode); | 323 | gfs2_set_inode_flags(&ip->i_inode); |
318 | height = be16_to_cpu(str->di_height); | 324 | height = be16_to_cpu(str->di_height); |
319 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) | 325 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) |
@@ -326,7 +332,6 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
326 | ip->i_depth = (u8)depth; | 332 | ip->i_depth = (u8)depth; |
327 | ip->i_entries = be32_to_cpu(str->di_entries); | 333 | ip->i_entries = be32_to_cpu(str->di_entries); |
328 | 334 | ||
329 | ip->i_eattr = be64_to_cpu(str->di_eattr); | ||
330 | if (S_ISREG(ip->i_inode.i_mode)) | 335 | if (S_ISREG(ip->i_inode.i_mode)) |
331 | gfs2_set_aops(&ip->i_inode); | 336 | gfs2_set_aops(&ip->i_inode); |
332 | 337 | ||
@@ -547,7 +552,6 @@ const struct gfs2_glock_operations gfs2_inode_glops = { | |||
547 | .go_lock = inode_go_lock, | 552 | .go_lock = inode_go_lock, |
548 | .go_dump = inode_go_dump, | 553 | .go_dump = inode_go_dump, |
549 | .go_type = LM_TYPE_INODE, | 554 | .go_type = LM_TYPE_INODE, |
550 | .go_min_hold_time = HZ / 5, | ||
551 | .go_flags = GLOF_ASPACE, | 555 | .go_flags = GLOF_ASPACE, |
552 | }; | 556 | }; |
553 | 557 | ||
@@ -558,7 +562,6 @@ const struct gfs2_glock_operations gfs2_rgrp_glops = { | |||
558 | .go_unlock = rgrp_go_unlock, | 562 | .go_unlock = rgrp_go_unlock, |
559 | .go_dump = gfs2_rgrp_dump, | 563 | .go_dump = gfs2_rgrp_dump, |
560 | .go_type = LM_TYPE_RGRP, | 564 | .go_type = LM_TYPE_RGRP, |
561 | .go_min_hold_time = HZ / 5, | ||
562 | .go_flags = GLOF_ASPACE, | 565 | .go_flags = GLOF_ASPACE, |
563 | }; | 566 | }; |
564 | 567 | ||
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 0a064e91ac70..892ac37de8ae 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/buffer_head.h> | 17 | #include <linux/buffer_head.h> |
18 | #include <linux/rcupdate.h> | 18 | #include <linux/rcupdate.h> |
19 | #include <linux/rculist_bl.h> | 19 | #include <linux/rculist_bl.h> |
20 | #include <linux/completion.h> | ||
20 | 21 | ||
21 | #define DIO_WAIT 0x00000010 | 22 | #define DIO_WAIT 0x00000010 |
22 | #define DIO_METADATA 0x00000020 | 23 | #define DIO_METADATA 0x00000020 |
@@ -162,7 +163,6 @@ struct gfs2_glock_operations { | |||
162 | int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); | 163 | int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); |
163 | void (*go_callback) (struct gfs2_glock *gl); | 164 | void (*go_callback) (struct gfs2_glock *gl); |
164 | const int go_type; | 165 | const int go_type; |
165 | const unsigned long go_min_hold_time; | ||
166 | const unsigned long go_flags; | 166 | const unsigned long go_flags; |
167 | #define GLOF_ASPACE 1 | 167 | #define GLOF_ASPACE 1 |
168 | }; | 168 | }; |
@@ -220,6 +220,7 @@ struct gfs2_glock { | |||
220 | 220 | ||
221 | unsigned int gl_hash; | 221 | unsigned int gl_hash; |
222 | unsigned long gl_demote_time; /* time of first demote request */ | 222 | unsigned long gl_demote_time; /* time of first demote request */ |
223 | long gl_hold_time; | ||
223 | struct list_head gl_holders; | 224 | struct list_head gl_holders; |
224 | 225 | ||
225 | const struct gfs2_glock_operations *gl_ops; | 226 | const struct gfs2_glock_operations *gl_ops; |
@@ -284,6 +285,7 @@ struct gfs2_inode { | |||
284 | u64 i_goal; /* goal block for allocations */ | 285 | u64 i_goal; /* goal block for allocations */ |
285 | struct rw_semaphore i_rw_mutex; | 286 | struct rw_semaphore i_rw_mutex; |
286 | struct list_head i_trunc_list; | 287 | struct list_head i_trunc_list; |
288 | __be64 *i_hash_cache; | ||
287 | u32 i_entries; | 289 | u32 i_entries; |
288 | u32 i_diskflags; | 290 | u32 i_diskflags; |
289 | u8 i_height; | 291 | u8 i_height; |
@@ -546,6 +548,7 @@ struct gfs2_sbd { | |||
546 | struct gfs2_glock *sd_trans_gl; | 548 | struct gfs2_glock *sd_trans_gl; |
547 | wait_queue_head_t sd_glock_wait; | 549 | wait_queue_head_t sd_glock_wait; |
548 | atomic_t sd_glock_disposal; | 550 | atomic_t sd_glock_disposal; |
551 | struct completion sd_locking_init; | ||
549 | 552 | ||
550 | /* Inode Stuff */ | 553 | /* Inode Stuff */ |
551 | 554 | ||
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 1d3a1a651721..6525b804d5ec 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -307,7 +307,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
307 | } | 307 | } |
308 | 308 | ||
309 | if (!is_root) { | 309 | if (!is_root) { |
310 | error = gfs2_permission(dir, MAY_EXEC, 0); | 310 | error = gfs2_permission(dir, MAY_EXEC); |
311 | if (error) | 311 | if (error) |
312 | goto out; | 312 | goto out; |
313 | } | 313 | } |
@@ -337,7 +337,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
337 | { | 337 | { |
338 | int error; | 338 | int error; |
339 | 339 | ||
340 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC, 0); | 340 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); |
341 | if (error) | 341 | if (error) |
342 | return error; | 342 | return error; |
343 | 343 | ||
@@ -790,13 +790,8 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
790 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | 790 | static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, |
791 | struct nameidata *nd) | 791 | struct nameidata *nd) |
792 | { | 792 | { |
793 | struct inode *inode = NULL; | 793 | struct inode *inode = gfs2_lookupi(dir, &dentry->d_name, 0); |
794 | 794 | if (inode && !IS_ERR(inode)) { | |
795 | inode = gfs2_lookupi(dir, &dentry->d_name, 0); | ||
796 | if (inode && IS_ERR(inode)) | ||
797 | return ERR_CAST(inode); | ||
798 | |||
799 | if (inode) { | ||
800 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; | 795 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; |
801 | struct gfs2_holder gh; | 796 | struct gfs2_holder gh; |
802 | int error; | 797 | int error; |
@@ -806,11 +801,8 @@ static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
806 | return ERR_PTR(error); | 801 | return ERR_PTR(error); |
807 | } | 802 | } |
808 | gfs2_glock_dq_uninit(&gh); | 803 | gfs2_glock_dq_uninit(&gh); |
809 | return d_splice_alias(inode, dentry); | ||
810 | } | 804 | } |
811 | d_add(dentry, inode); | 805 | return d_splice_alias(inode, dentry); |
812 | |||
813 | return NULL; | ||
814 | } | 806 | } |
815 | 807 | ||
816 | /** | 808 | /** |
@@ -855,7 +847,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
855 | if (inode->i_nlink == 0) | 847 | if (inode->i_nlink == 0) |
856 | goto out_gunlock; | 848 | goto out_gunlock; |
857 | 849 | ||
858 | error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC, 0); | 850 | error = gfs2_permission(dir, MAY_WRITE | MAY_EXEC); |
859 | if (error) | 851 | if (error) |
860 | goto out_gunlock; | 852 | goto out_gunlock; |
861 | 853 | ||
@@ -988,7 +980,7 @@ static int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
988 | if (IS_APPEND(&dip->i_inode)) | 980 | if (IS_APPEND(&dip->i_inode)) |
989 | return -EPERM; | 981 | return -EPERM; |
990 | 982 | ||
991 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC, 0); | 983 | error = gfs2_permission(&dip->i_inode, MAY_WRITE | MAY_EXEC); |
992 | if (error) | 984 | if (error) |
993 | return error; | 985 | return error; |
994 | 986 | ||
@@ -1334,7 +1326,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1334 | } | 1326 | } |
1335 | } | 1327 | } |
1336 | } else { | 1328 | } else { |
1337 | error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC, 0); | 1329 | error = gfs2_permission(ndir, MAY_WRITE | MAY_EXEC); |
1338 | if (error) | 1330 | if (error) |
1339 | goto out_gunlock; | 1331 | goto out_gunlock; |
1340 | 1332 | ||
@@ -1369,7 +1361,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1369 | /* Check out the dir to be renamed */ | 1361 | /* Check out the dir to be renamed */ |
1370 | 1362 | ||
1371 | if (dir_rename) { | 1363 | if (dir_rename) { |
1372 | error = gfs2_permission(odentry->d_inode, MAY_WRITE, 0); | 1364 | error = gfs2_permission(odentry->d_inode, MAY_WRITE); |
1373 | if (error) | 1365 | if (error) |
1374 | goto out_gunlock; | 1366 | goto out_gunlock; |
1375 | } | 1367 | } |
@@ -1541,7 +1533,7 @@ static void gfs2_put_link(struct dentry *dentry, struct nameidata *nd, void *p) | |||
1541 | * Returns: errno | 1533 | * Returns: errno |
1542 | */ | 1534 | */ |
1543 | 1535 | ||
1544 | int gfs2_permission(struct inode *inode, int mask, unsigned int flags) | 1536 | int gfs2_permission(struct inode *inode, int mask) |
1545 | { | 1537 | { |
1546 | struct gfs2_inode *ip; | 1538 | struct gfs2_inode *ip; |
1547 | struct gfs2_holder i_gh; | 1539 | struct gfs2_holder i_gh; |
@@ -1551,7 +1543,7 @@ int gfs2_permission(struct inode *inode, int mask, unsigned int flags) | |||
1551 | 1543 | ||
1552 | ip = GFS2_I(inode); | 1544 | ip = GFS2_I(inode); |
1553 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { | 1545 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == NULL) { |
1554 | if (flags & IPERM_FLAG_RCU) | 1546 | if (mask & MAY_NOT_BLOCK) |
1555 | return -ECHILD; | 1547 | return -ECHILD; |
1556 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | 1548 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); |
1557 | if (error) | 1549 | if (error) |
@@ -1562,7 +1554,7 @@ int gfs2_permission(struct inode *inode, int mask, unsigned int flags) | |||
1562 | if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) | 1554 | if ((mask & MAY_WRITE) && IS_IMMUTABLE(inode)) |
1563 | error = -EACCES; | 1555 | error = -EACCES; |
1564 | else | 1556 | else |
1565 | error = generic_permission(inode, mask, flags, gfs2_check_acl); | 1557 | error = generic_permission(inode, mask); |
1566 | if (unlock) | 1558 | if (unlock) |
1567 | gfs2_glock_dq_uninit(&i_gh); | 1559 | gfs2_glock_dq_uninit(&i_gh); |
1568 | 1560 | ||
@@ -1852,6 +1844,7 @@ const struct inode_operations gfs2_file_iops = { | |||
1852 | .listxattr = gfs2_listxattr, | 1844 | .listxattr = gfs2_listxattr, |
1853 | .removexattr = gfs2_removexattr, | 1845 | .removexattr = gfs2_removexattr, |
1854 | .fiemap = gfs2_fiemap, | 1846 | .fiemap = gfs2_fiemap, |
1847 | .get_acl = gfs2_get_acl, | ||
1855 | }; | 1848 | }; |
1856 | 1849 | ||
1857 | const struct inode_operations gfs2_dir_iops = { | 1850 | const struct inode_operations gfs2_dir_iops = { |
@@ -1872,6 +1865,7 @@ const struct inode_operations gfs2_dir_iops = { | |||
1872 | .listxattr = gfs2_listxattr, | 1865 | .listxattr = gfs2_listxattr, |
1873 | .removexattr = gfs2_removexattr, | 1866 | .removexattr = gfs2_removexattr, |
1874 | .fiemap = gfs2_fiemap, | 1867 | .fiemap = gfs2_fiemap, |
1868 | .get_acl = gfs2_get_acl, | ||
1875 | }; | 1869 | }; |
1876 | 1870 | ||
1877 | const struct inode_operations gfs2_symlink_iops = { | 1871 | const struct inode_operations gfs2_symlink_iops = { |
@@ -1886,5 +1880,6 @@ const struct inode_operations gfs2_symlink_iops = { | |||
1886 | .listxattr = gfs2_listxattr, | 1880 | .listxattr = gfs2_listxattr, |
1887 | .removexattr = gfs2_removexattr, | 1881 | .removexattr = gfs2_removexattr, |
1888 | .fiemap = gfs2_fiemap, | 1882 | .fiemap = gfs2_fiemap, |
1883 | .get_acl = gfs2_get_acl, | ||
1889 | }; | 1884 | }; |
1890 | 1885 | ||
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 31606076f701..8d90e0c07672 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -108,7 +108,7 @@ extern int gfs2_inode_refresh(struct gfs2_inode *ip); | |||
108 | 108 | ||
109 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 109 | extern struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
110 | int is_root); | 110 | int is_root); |
111 | extern int gfs2_permission(struct inode *inode, int mask, unsigned int flags); | 111 | extern int gfs2_permission(struct inode *inode, int mask); |
112 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 112 | extern int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
113 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 113 | extern struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
114 | extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); | 114 | extern void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 903115f2bb34..85c62923ee29 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -903,6 +903,7 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | |||
903 | if (gfs2_ail1_empty(sdp)) | 903 | if (gfs2_ail1_empty(sdp)) |
904 | break; | 904 | break; |
905 | } | 905 | } |
906 | gfs2_log_flush(sdp, NULL); | ||
906 | } | 907 | } |
907 | 908 | ||
908 | static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) | 909 | static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index c2b34cd2abe0..8a139ff1919f 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/gfs2_ondisk.h> | 16 | #include <linux/gfs2_ondisk.h> |
17 | #include <linux/rcupdate.h> | 17 | #include <linux/rcupdate.h> |
18 | #include <linux/rculist_bl.h> | 18 | #include <linux/rculist_bl.h> |
19 | #include <asm/atomic.h> | 19 | #include <linux/atomic.h> |
20 | 20 | ||
21 | #include "gfs2.h" | 21 | #include "gfs2.h" |
22 | #include "incore.h" | 22 | #include "incore.h" |
@@ -41,6 +41,7 @@ static void gfs2_init_inode_once(void *foo) | |||
41 | init_rwsem(&ip->i_rw_mutex); | 41 | init_rwsem(&ip->i_rw_mutex); |
42 | INIT_LIST_HEAD(&ip->i_trunc_list); | 42 | INIT_LIST_HEAD(&ip->i_trunc_list); |
43 | ip->i_alloc = NULL; | 43 | ip->i_alloc = NULL; |
44 | ip->i_hash_cache = NULL; | ||
44 | } | 45 | } |
45 | 46 | ||
46 | static void gfs2_init_glock_once(void *foo) | 47 | static void gfs2_init_glock_once(void *foo) |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 8ac9ae189b53..3bc073a4cf82 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -72,6 +72,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
72 | 72 | ||
73 | init_waitqueue_head(&sdp->sd_glock_wait); | 73 | init_waitqueue_head(&sdp->sd_glock_wait); |
74 | atomic_set(&sdp->sd_glock_disposal, 0); | 74 | atomic_set(&sdp->sd_glock_disposal, 0); |
75 | init_completion(&sdp->sd_locking_init); | ||
75 | spin_lock_init(&sdp->sd_statfs_spin); | 76 | spin_lock_init(&sdp->sd_statfs_spin); |
76 | 77 | ||
77 | spin_lock_init(&sdp->sd_rindex_spin); | 78 | spin_lock_init(&sdp->sd_rindex_spin); |
@@ -1017,11 +1018,13 @@ hostdata_error: | |||
1017 | fsname++; | 1018 | fsname++; |
1018 | if (lm->lm_mount == NULL) { | 1019 | if (lm->lm_mount == NULL) { |
1019 | fs_info(sdp, "Now mounting FS...\n"); | 1020 | fs_info(sdp, "Now mounting FS...\n"); |
1021 | complete_all(&sdp->sd_locking_init); | ||
1020 | return 0; | 1022 | return 0; |
1021 | } | 1023 | } |
1022 | ret = lm->lm_mount(sdp, fsname); | 1024 | ret = lm->lm_mount(sdp, fsname); |
1023 | if (ret == 0) | 1025 | if (ret == 0) |
1024 | fs_info(sdp, "Joined cluster. Now mounting FS...\n"); | 1026 | fs_info(sdp, "Joined cluster. Now mounting FS...\n"); |
1027 | complete_all(&sdp->sd_locking_init); | ||
1025 | return ret; | 1028 | return ret; |
1026 | } | 1029 | } |
1027 | 1030 | ||
@@ -1091,6 +1094,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent | |||
1091 | if (sdp->sd_args.ar_nobarrier) | 1094 | if (sdp->sd_args.ar_nobarrier) |
1092 | set_bit(SDF_NOBARRIERS, &sdp->sd_flags); | 1095 | set_bit(SDF_NOBARRIERS, &sdp->sd_flags); |
1093 | 1096 | ||
1097 | sb->s_flags |= MS_NOSEC; | ||
1094 | sb->s_magic = GFS2_MAGIC; | 1098 | sb->s_magic = GFS2_MAGIC; |
1095 | sb->s_op = &gfs2_super_ops; | 1099 | sb->s_op = &gfs2_super_ops; |
1096 | sb->s_d_op = &gfs2_dops; | 1100 | sb->s_d_op = &gfs2_dops; |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 9b780df3fd54..7f8af1eb02de 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -1607,14 +1607,15 @@ rgrp_error: | |||
1607 | } | 1607 | } |
1608 | 1608 | ||
1609 | /** | 1609 | /** |
1610 | * gfs2_free_data - free a contiguous run of data block(s) | 1610 | * __gfs2_free_blocks - free a contiguous run of block(s) |
1611 | * @ip: the inode these blocks are being freed from | 1611 | * @ip: the inode these blocks are being freed from |
1612 | * @bstart: first block of a run of contiguous blocks | 1612 | * @bstart: first block of a run of contiguous blocks |
1613 | * @blen: the length of the block run | 1613 | * @blen: the length of the block run |
1614 | * @meta: 1 if the blocks represent metadata | ||
1614 | * | 1615 | * |
1615 | */ | 1616 | */ |
1616 | 1617 | ||
1617 | void __gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | 1618 | void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta) |
1618 | { | 1619 | { |
1619 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1620 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1620 | struct gfs2_rgrpd *rgd; | 1621 | struct gfs2_rgrpd *rgd; |
@@ -1631,54 +1632,11 @@ void __gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1631 | gfs2_trans_add_rg(rgd); | 1632 | gfs2_trans_add_rg(rgd); |
1632 | 1633 | ||
1633 | /* Directories keep their data in the metadata address space */ | 1634 | /* Directories keep their data in the metadata address space */ |
1634 | if (ip->i_depth) | 1635 | if (meta || ip->i_depth) |
1635 | gfs2_meta_wipe(ip, bstart, blen); | 1636 | gfs2_meta_wipe(ip, bstart, blen); |
1636 | } | 1637 | } |
1637 | 1638 | ||
1638 | /** | 1639 | /** |
1639 | * gfs2_free_data - free a contiguous run of data block(s) | ||
1640 | * @ip: the inode these blocks are being freed from | ||
1641 | * @bstart: first block of a run of contiguous blocks | ||
1642 | * @blen: the length of the block run | ||
1643 | * | ||
1644 | */ | ||
1645 | |||
1646 | void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | ||
1647 | { | ||
1648 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1649 | |||
1650 | __gfs2_free_data(ip, bstart, blen); | ||
1651 | gfs2_statfs_change(sdp, 0, +blen, 0); | ||
1652 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); | ||
1653 | } | ||
1654 | |||
1655 | /** | ||
1656 | * gfs2_free_meta - free a contiguous run of data block(s) | ||
1657 | * @ip: the inode these blocks are being freed from | ||
1658 | * @bstart: first block of a run of contiguous blocks | ||
1659 | * @blen: the length of the block run | ||
1660 | * | ||
1661 | */ | ||
1662 | |||
1663 | void __gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen) | ||
1664 | { | ||
1665 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1666 | struct gfs2_rgrpd *rgd; | ||
1667 | |||
1668 | rgd = rgblk_free(sdp, bstart, blen, GFS2_BLKST_FREE); | ||
1669 | if (!rgd) | ||
1670 | return; | ||
1671 | trace_gfs2_block_alloc(ip, bstart, blen, GFS2_BLKST_FREE); | ||
1672 | rgd->rd_free += blen; | ||
1673 | |||
1674 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | ||
1675 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | ||
1676 | |||
1677 | gfs2_trans_add_rg(rgd); | ||
1678 | gfs2_meta_wipe(ip, bstart, blen); | ||
1679 | } | ||
1680 | |||
1681 | /** | ||
1682 | * gfs2_free_meta - free a contiguous run of data block(s) | 1640 | * gfs2_free_meta - free a contiguous run of data block(s) |
1683 | * @ip: the inode these blocks are being freed from | 1641 | * @ip: the inode these blocks are being freed from |
1684 | * @bstart: first block of a run of contiguous blocks | 1642 | * @bstart: first block of a run of contiguous blocks |
@@ -1690,7 +1648,7 @@ void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1690 | { | 1648 | { |
1691 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1649 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1692 | 1650 | ||
1693 | __gfs2_free_meta(ip, bstart, blen); | 1651 | __gfs2_free_blocks(ip, bstart, blen, 1); |
1694 | gfs2_statfs_change(sdp, 0, +blen, 0); | 1652 | gfs2_statfs_change(sdp, 0, +blen, 0); |
1695 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); | 1653 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1696 | } | 1654 | } |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index a80e3034ac47..d253f9a8c70e 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
@@ -52,9 +52,7 @@ extern int gfs2_ri_update(struct gfs2_inode *ip); | |||
52 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); | 52 | extern int gfs2_alloc_block(struct gfs2_inode *ip, u64 *bn, unsigned int *n); |
53 | extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); | 53 | extern int gfs2_alloc_di(struct gfs2_inode *ip, u64 *bn, u64 *generation); |
54 | 54 | ||
55 | extern void __gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen); | 55 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); |
56 | extern void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen); | ||
57 | extern void __gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | ||
58 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); | 56 | extern void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen); |
59 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); | 57 | extern void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip); |
60 | extern void gfs2_unlink_di(struct inode *inode); | 58 | extern void gfs2_unlink_di(struct inode *inode); |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index ed540e7018be..b7beadd9ba4c 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -757,13 +757,17 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
757 | struct timespec atime; | 757 | struct timespec atime; |
758 | struct gfs2_dinode *di; | 758 | struct gfs2_dinode *di; |
759 | int ret = -EAGAIN; | 759 | int ret = -EAGAIN; |
760 | int unlock_required = 0; | ||
760 | 761 | ||
761 | /* Skip timestamp update, if this is from a memalloc */ | 762 | /* Skip timestamp update, if this is from a memalloc */ |
762 | if (current->flags & PF_MEMALLOC) | 763 | if (current->flags & PF_MEMALLOC) |
763 | goto do_flush; | 764 | goto do_flush; |
764 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 765 | if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { |
765 | if (ret) | 766 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
766 | goto do_flush; | 767 | if (ret) |
768 | goto do_flush; | ||
769 | unlock_required = 1; | ||
770 | } | ||
767 | ret = gfs2_trans_begin(sdp, RES_DINODE, 0); | 771 | ret = gfs2_trans_begin(sdp, RES_DINODE, 0); |
768 | if (ret) | 772 | if (ret) |
769 | goto do_unlock; | 773 | goto do_unlock; |
@@ -780,7 +784,8 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
780 | } | 784 | } |
781 | gfs2_trans_end(sdp); | 785 | gfs2_trans_end(sdp); |
782 | do_unlock: | 786 | do_unlock: |
783 | gfs2_glock_dq_uninit(&gh); | 787 | if (unlock_required) |
788 | gfs2_glock_dq_uninit(&gh); | ||
784 | do_flush: | 789 | do_flush: |
785 | if (wbc->sync_mode == WB_SYNC_ALL) | 790 | if (wbc->sync_mode == WB_SYNC_ALL) |
786 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | 791 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); |
@@ -1427,7 +1432,20 @@ out: | |||
1427 | return error; | 1432 | return error; |
1428 | } | 1433 | } |
1429 | 1434 | ||
1430 | /* | 1435 | /** |
1436 | * gfs2_evict_inode - Remove an inode from cache | ||
1437 | * @inode: The inode to evict | ||
1438 | * | ||
1439 | * There are three cases to consider: | ||
1440 | * 1. i_nlink == 0, we are final opener (and must deallocate) | ||
1441 | * 2. i_nlink == 0, we are not the final opener (and cannot deallocate) | ||
1442 | * 3. i_nlink > 0 | ||
1443 | * | ||
1444 | * If the fs is read only, then we have to treat all cases as per #3 | ||
1445 | * since we are unable to do any deallocation. The inode will be | ||
1446 | * deallocated by the next read/write node to attempt an allocation | ||
1447 | * in the same resource group | ||
1448 | * | ||
1431 | * We have to (at the moment) hold the inodes main lock to cover | 1449 | * We have to (at the moment) hold the inodes main lock to cover |
1432 | * the gap between unlocking the shared lock on the iopen lock and | 1450 | * the gap between unlocking the shared lock on the iopen lock and |
1433 | * taking the exclusive lock. I'd rather do a shared -> exclusive | 1451 | * taking the exclusive lock. I'd rather do a shared -> exclusive |
@@ -1470,6 +1488,8 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1470 | if (error) | 1488 | if (error) |
1471 | goto out_truncate; | 1489 | goto out_truncate; |
1472 | 1490 | ||
1491 | /* Case 1 starts here */ | ||
1492 | |||
1473 | if (S_ISDIR(inode->i_mode) && | 1493 | if (S_ISDIR(inode->i_mode) && |
1474 | (ip->i_diskflags & GFS2_DIF_EXHASH)) { | 1494 | (ip->i_diskflags & GFS2_DIF_EXHASH)) { |
1475 | error = gfs2_dir_exhash_dealloc(ip); | 1495 | error = gfs2_dir_exhash_dealloc(ip); |
@@ -1493,13 +1513,16 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1493 | goto out_unlock; | 1513 | goto out_unlock; |
1494 | 1514 | ||
1495 | out_truncate: | 1515 | out_truncate: |
1516 | /* Case 2 starts here */ | ||
1496 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 1517 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
1497 | if (error) | 1518 | if (error) |
1498 | goto out_unlock; | 1519 | goto out_unlock; |
1499 | gfs2_final_release_pages(ip); | 1520 | /* Needs to be done before glock release & also in a transaction */ |
1521 | truncate_inode_pages(&inode->i_data, 0); | ||
1500 | gfs2_trans_end(sdp); | 1522 | gfs2_trans_end(sdp); |
1501 | 1523 | ||
1502 | out_unlock: | 1524 | out_unlock: |
1525 | /* Error path for case 1 */ | ||
1503 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) | 1526 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) |
1504 | gfs2_glock_dq(&ip->i_iopen_gh); | 1527 | gfs2_glock_dq(&ip->i_iopen_gh); |
1505 | gfs2_holder_uninit(&ip->i_iopen_gh); | 1528 | gfs2_holder_uninit(&ip->i_iopen_gh); |
@@ -1507,9 +1530,10 @@ out_unlock: | |||
1507 | if (error && error != GLR_TRYFAILED && error != -EROFS) | 1530 | if (error && error != GLR_TRYFAILED && error != -EROFS) |
1508 | fs_warn(sdp, "gfs2_evict_inode: %d\n", error); | 1531 | fs_warn(sdp, "gfs2_evict_inode: %d\n", error); |
1509 | out: | 1532 | out: |
1533 | /* Case 3 starts here */ | ||
1510 | truncate_inode_pages(&inode->i_data, 0); | 1534 | truncate_inode_pages(&inode->i_data, 0); |
1511 | end_writeback(inode); | 1535 | end_writeback(inode); |
1512 | 1536 | gfs2_dir_hash_inval(ip); | |
1513 | ip->i_gl->gl_object = NULL; | 1537 | ip->i_gl->gl_object = NULL; |
1514 | gfs2_glock_add_to_lru(ip->i_gl); | 1538 | gfs2_glock_add_to_lru(ip->i_gl); |
1515 | gfs2_glock_put(ip->i_gl); | 1539 | gfs2_glock_put(ip->i_gl); |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index e20eab37bc80..443cabcfcd23 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -338,6 +338,9 @@ static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | |||
338 | rv = sscanf(buf, "%u", &first); | 338 | rv = sscanf(buf, "%u", &first); |
339 | if (rv != 1 || first > 1) | 339 | if (rv != 1 || first > 1) |
340 | return -EINVAL; | 340 | return -EINVAL; |
341 | rv = wait_for_completion_killable(&sdp->sd_locking_init); | ||
342 | if (rv) | ||
343 | return rv; | ||
341 | spin_lock(&sdp->sd_jindex_spin); | 344 | spin_lock(&sdp->sd_jindex_spin); |
342 | rv = -EBUSY; | 345 | rv = -EBUSY; |
343 | if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) | 346 | if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) |
@@ -414,7 +417,9 @@ static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | |||
414 | rv = sscanf(buf, "%d", &jid); | 417 | rv = sscanf(buf, "%d", &jid); |
415 | if (rv != 1) | 418 | if (rv != 1) |
416 | return -EINVAL; | 419 | return -EINVAL; |
417 | 420 | rv = wait_for_completion_killable(&sdp->sd_locking_init); | |
421 | if (rv) | ||
422 | return rv; | ||
418 | spin_lock(&sdp->sd_jindex_spin); | 423 | spin_lock(&sdp->sd_jindex_spin); |
419 | rv = -EINVAL; | 424 | rv = -EINVAL; |
420 | if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) | 425 | if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) |