diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-12 21:09:35 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-12 21:09:35 -0500 |
commit | 4d58967783611c5676820b8d47a9b6b0bb456995 (patch) | |
tree | 6a20281fbff1a1a4e88d65d5851e51d8d6b2f02e | |
parent | 33caf82acf4dc420bf0f0136b886f7b27ecf90c5 (diff) | |
parent | a93a99838248bdab49db2eaac00236847670bc7f (diff) |
Merge tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull GFS2 updates from Bob Peterson:
"Here is a list of patches we've accumulated for GFS2 for the current
upstream merge window. Last window's set was short, but I warned that
this one would be bigger, and so it is. We've got 19 patches:
- A patch from Abhi Das to propagate the GFS2_DIF_SYSTEM bit so that
newly added journals don't get flagged, deleted, and recreated by
fsck.gfs2.
- Two patches from Andreas Gruenbacher to improve GFS2 performance
where extended attributes are involved.
- A patch from Andy Price to fix a suspicious rcu dereference error.
- Two patches from Ben Marzinski that rework how GFS2's NFS cookies
are managed. This fixes readdir problems with nfs-over-gfs2.
- A patch from Ben Marzinski that fixes a race in unmounting GFS2.
- A set of four patches from me to move the resource group
reservations inside the gfs2 inode to improve performance and fix a
bug whereby get_write_access improperly prevented some operations
like chown.
- A patch from me to spinlock-protect the setting of system statfs
file data. This was causing small discrepancies between df and du.
- A patch from me to reintroduce a timeout while clearing glocks
which was accidentally dropped some time ago.
- A patch from me to wait for iopen glock dequeues in order to
improve deleting of files that were unlinked from a different
cluster node.
- A patch from me to ensure metadata address spaces get truncated
when an inode is evicted.
- A patch from me to fix a bug in which a memory leak could occur in
some error cases when inodes were trying to be created.
- A patch to consistently use iopen glocks to transition from the
unlinked state to the deleted state.
- A patch to fix a glock reference count error when inode creation
fails.
- A patch from Junxiao Bi to fix an flock panic.
- A patch from Markus Elfring that removes an unnecessary if"
* tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
gfs2: fix flock panic issue
GFS2: Don't do glock put on when inode creation fails
GFS2: Always use iopen glock for gl_deletes
GFS2: Release iopen glock in gfs2_create_inode error cases
GFS2: Truncate address space mapping when deleting an inode
GFS2: Wait for iopen glock dequeues
gfs2: clear journal live bit in gfs2_log_flush
gfs2: change gfs2 readdir cookie
gfs2: keep offset when splitting dir leaf blocks
GFS2: Reintroduce a timeout in function gfs2_gl_hash_clear
GFS2: Update master statfs buffer with sd_statfs_spin locked
GFS2: Reduce size of incore inode
GFS2: Make rgrp reservations part of the gfs2_inode structure
GFS2: Extract quota data from reservations structure (revert 5407e24)
gfs2: Extended attribute readahead optimization
gfs2: Extended attribute readahead
GFS2: Use rht_for_each_entry_rcu in glock_hash_walk
GFS2: Delete an unnecessary check before the function call "iput"
gfs2: Automatically set GFS2_DIF_SYSTEM flag on system files
-rw-r--r-- | fs/gfs2/aops.c | 2 | ||||
-rw-r--r-- | fs/gfs2/bmap.c | 13 | ||||
-rw-r--r-- | fs/gfs2/dir.c | 175 | ||||
-rw-r--r-- | fs/gfs2/file.c | 34 | ||||
-rw-r--r-- | fs/gfs2/glock.c | 18 | ||||
-rw-r--r-- | fs/gfs2/glock.h | 26 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 23 | ||||
-rw-r--r-- | fs/gfs2/inode.c | 48 | ||||
-rw-r--r-- | fs/gfs2/log.c | 3 | ||||
-rw-r--r-- | fs/gfs2/main.c | 16 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 82 | ||||
-rw-r--r-- | fs/gfs2/meta_io.h | 2 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 6 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 117 | ||||
-rw-r--r-- | fs/gfs2/quota.h | 2 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 57 | ||||
-rw-r--r-- | fs/gfs2/rgrp.h | 6 | ||||
-rw-r--r-- | fs/gfs2/super.c | 43 | ||||
-rw-r--r-- | fs/gfs2/util.c | 2 | ||||
-rw-r--r-- | fs/gfs2/util.h | 2 | ||||
-rw-r--r-- | fs/gfs2/xattr.c | 10 | ||||
-rw-r--r-- | include/uapi/linux/gfs2_ondisk.h | 9 |
22 files changed, 452 insertions, 244 deletions
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 1caee0534587..93f07465e5a6 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -914,7 +914,7 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
914 | failed: | 914 | failed: |
915 | gfs2_trans_end(sdp); | 915 | gfs2_trans_end(sdp); |
916 | gfs2_inplace_release(ip); | 916 | gfs2_inplace_release(ip); |
917 | if (ip->i_res->rs_qa_qd_num) | 917 | if (ip->i_qadata && ip->i_qadata->qa_qd_num) |
918 | gfs2_quota_unlock(ip); | 918 | gfs2_quota_unlock(ip); |
919 | if (inode == sdp->sd_rindex) { | 919 | if (inode == sdp->sd_rindex) { |
920 | gfs2_glock_dq(&m_ip->i_gh); | 920 | gfs2_glock_dq(&m_ip->i_gh); |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 61296ecbd0e2..0860f0b5b3f1 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -787,8 +787,8 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
787 | if (error) | 787 | if (error) |
788 | goto out_rlist; | 788 | goto out_rlist; |
789 | 789 | ||
790 | if (gfs2_rs_active(ip->i_res)) /* needs to be done with the rgrp glock held */ | 790 | if (gfs2_rs_active(&ip->i_res)) /* needs to be done with the rgrp glock held */ |
791 | gfs2_rs_deltree(ip->i_res); | 791 | gfs2_rs_deltree(&ip->i_res); |
792 | 792 | ||
793 | error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + | 793 | error = gfs2_trans_begin(sdp, rg_blocks + RES_DINODE + |
794 | RES_INDIRECT + RES_STATFS + RES_QUOTA, | 794 | RES_INDIRECT + RES_STATFS + RES_QUOTA, |
@@ -1291,13 +1291,9 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize) | |||
1291 | if (ret) | 1291 | if (ret) |
1292 | return ret; | 1292 | return ret; |
1293 | 1293 | ||
1294 | ret = get_write_access(inode); | ||
1295 | if (ret) | ||
1296 | return ret; | ||
1297 | |||
1298 | inode_dio_wait(inode); | 1294 | inode_dio_wait(inode); |
1299 | 1295 | ||
1300 | ret = gfs2_rs_alloc(ip); | 1296 | ret = gfs2_rsqa_alloc(ip); |
1301 | if (ret) | 1297 | if (ret) |
1302 | goto out; | 1298 | goto out; |
1303 | 1299 | ||
@@ -1307,10 +1303,9 @@ int gfs2_setattr_size(struct inode *inode, u64 newsize) | |||
1307 | goto out; | 1303 | goto out; |
1308 | } | 1304 | } |
1309 | 1305 | ||
1310 | gfs2_rs_deltree(ip->i_res); | ||
1311 | ret = do_shrink(inode, oldsize, newsize); | 1306 | ret = do_shrink(inode, oldsize, newsize); |
1312 | out: | 1307 | out: |
1313 | put_write_access(inode); | 1308 | gfs2_rsqa_delete(ip, NULL); |
1314 | return ret; | 1309 | return ret; |
1315 | } | 1310 | } |
1316 | 1311 | ||
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index ad8a5b757cc7..6a92592304fb 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -82,6 +82,8 @@ | |||
82 | 82 | ||
83 | #define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1) | 83 | #define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1) |
84 | #define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1)) | 84 | #define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1)) |
85 | #define GFS2_HASH_INDEX_MASK 0xffffc000 | ||
86 | #define GFS2_USE_HASH_FLAG 0x2000 | ||
85 | 87 | ||
86 | struct qstr gfs2_qdot __read_mostly; | 88 | struct qstr gfs2_qdot __read_mostly; |
87 | struct qstr gfs2_qdotdot __read_mostly; | 89 | struct qstr gfs2_qdotdot __read_mostly; |
@@ -108,7 +110,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block, | |||
108 | struct buffer_head *bh; | 110 | struct buffer_head *bh; |
109 | int error; | 111 | int error; |
110 | 112 | ||
111 | error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, &bh); | 113 | error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, 0, &bh); |
112 | if (error) | 114 | if (error) |
113 | return error; | 115 | return error; |
114 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) { | 116 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) { |
@@ -305,7 +307,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, __be64 *buf, | |||
305 | BUG_ON(extlen < 1); | 307 | BUG_ON(extlen < 1); |
306 | bh = gfs2_meta_ra(ip->i_gl, dblock, extlen); | 308 | bh = gfs2_meta_ra(ip->i_gl, dblock, extlen); |
307 | } else { | 309 | } else { |
308 | error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh); | 310 | error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, 0, &bh); |
309 | if (error) | 311 | if (error) |
310 | goto fail; | 312 | goto fail; |
311 | } | 313 | } |
@@ -443,6 +445,27 @@ static int gfs2_dirent_last(const struct gfs2_dirent *dent, | |||
443 | return 0; | 445 | return 0; |
444 | } | 446 | } |
445 | 447 | ||
448 | /* Look for the dirent that contains the offset specified in data. Once we | ||
449 | * find that dirent, there must be space available there for the new dirent */ | ||
450 | static int gfs2_dirent_find_offset(const struct gfs2_dirent *dent, | ||
451 | const struct qstr *name, | ||
452 | void *ptr) | ||
453 | { | ||
454 | unsigned required = GFS2_DIRENT_SIZE(name->len); | ||
455 | unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); | ||
456 | unsigned totlen = be16_to_cpu(dent->de_rec_len); | ||
457 | |||
458 | if (ptr < (void *)dent || ptr >= (void *)dent + totlen) | ||
459 | return 0; | ||
460 | if (gfs2_dirent_sentinel(dent)) | ||
461 | actual = 0; | ||
462 | if (ptr < (void *)dent + actual) | ||
463 | return -1; | ||
464 | if ((void *)dent + totlen >= ptr + required) | ||
465 | return 1; | ||
466 | return -1; | ||
467 | } | ||
468 | |||
446 | static int gfs2_dirent_find_space(const struct gfs2_dirent *dent, | 469 | static int gfs2_dirent_find_space(const struct gfs2_dirent *dent, |
447 | const struct qstr *name, | 470 | const struct qstr *name, |
448 | void *opaque) | 471 | void *opaque) |
@@ -682,6 +705,27 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh, | |||
682 | prev->de_rec_len = cpu_to_be16(prev_rec_len); | 705 | prev->de_rec_len = cpu_to_be16(prev_rec_len); |
683 | } | 706 | } |
684 | 707 | ||
708 | |||
709 | static struct gfs2_dirent *do_init_dirent(struct inode *inode, | ||
710 | struct gfs2_dirent *dent, | ||
711 | const struct qstr *name, | ||
712 | struct buffer_head *bh, | ||
713 | unsigned offset) | ||
714 | { | ||
715 | struct gfs2_inode *ip = GFS2_I(inode); | ||
716 | struct gfs2_dirent *ndent; | ||
717 | unsigned totlen; | ||
718 | |||
719 | totlen = be16_to_cpu(dent->de_rec_len); | ||
720 | BUG_ON(offset + name->len > totlen); | ||
721 | gfs2_trans_add_meta(ip->i_gl, bh); | ||
722 | ndent = (struct gfs2_dirent *)((char *)dent + offset); | ||
723 | dent->de_rec_len = cpu_to_be16(offset); | ||
724 | gfs2_qstr2dirent(name, totlen - offset, ndent); | ||
725 | return ndent; | ||
726 | } | ||
727 | |||
728 | |||
685 | /* | 729 | /* |
686 | * Takes a dent from which to grab space as an argument. Returns the | 730 | * Takes a dent from which to grab space as an argument. Returns the |
687 | * newly created dent. | 731 | * newly created dent. |
@@ -691,31 +735,25 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode, | |||
691 | const struct qstr *name, | 735 | const struct qstr *name, |
692 | struct buffer_head *bh) | 736 | struct buffer_head *bh) |
693 | { | 737 | { |
694 | struct gfs2_inode *ip = GFS2_I(inode); | 738 | unsigned offset = 0; |
695 | struct gfs2_dirent *ndent; | ||
696 | unsigned offset = 0, totlen; | ||
697 | 739 | ||
698 | if (!gfs2_dirent_sentinel(dent)) | 740 | if (!gfs2_dirent_sentinel(dent)) |
699 | offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); | 741 | offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); |
700 | totlen = be16_to_cpu(dent->de_rec_len); | 742 | return do_init_dirent(inode, dent, name, bh, offset); |
701 | BUG_ON(offset + name->len > totlen); | ||
702 | gfs2_trans_add_meta(ip->i_gl, bh); | ||
703 | ndent = (struct gfs2_dirent *)((char *)dent + offset); | ||
704 | dent->de_rec_len = cpu_to_be16(offset); | ||
705 | gfs2_qstr2dirent(name, totlen - offset, ndent); | ||
706 | return ndent; | ||
707 | } | 743 | } |
708 | 744 | ||
709 | static struct gfs2_dirent *gfs2_dirent_alloc(struct inode *inode, | 745 | static struct gfs2_dirent *gfs2_dirent_split_alloc(struct inode *inode, |
710 | struct buffer_head *bh, | 746 | struct buffer_head *bh, |
711 | const struct qstr *name) | 747 | const struct qstr *name, |
748 | void *ptr) | ||
712 | { | 749 | { |
713 | struct gfs2_dirent *dent; | 750 | struct gfs2_dirent *dent; |
714 | dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, | 751 | dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, |
715 | gfs2_dirent_find_space, name, NULL); | 752 | gfs2_dirent_find_offset, name, ptr); |
716 | if (!dent || IS_ERR(dent)) | 753 | if (!dent || IS_ERR(dent)) |
717 | return dent; | 754 | return dent; |
718 | return gfs2_init_dirent(inode, dent, name, bh); | 755 | return do_init_dirent(inode, dent, name, bh, |
756 | (unsigned)(ptr - (void *)dent)); | ||
719 | } | 757 | } |
720 | 758 | ||
721 | static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, | 759 | static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, |
@@ -723,7 +761,7 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, | |||
723 | { | 761 | { |
724 | int error; | 762 | int error; |
725 | 763 | ||
726 | error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, bhp); | 764 | error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, 0, bhp); |
727 | if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) { | 765 | if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) { |
728 | /* pr_info("block num=%llu\n", leaf_no); */ | 766 | /* pr_info("block num=%llu\n", leaf_no); */ |
729 | error = -EIO; | 767 | error = -EIO; |
@@ -1051,10 +1089,11 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
1051 | if (!gfs2_dirent_sentinel(dent) && | 1089 | if (!gfs2_dirent_sentinel(dent) && |
1052 | be32_to_cpu(dent->de_hash) < divider) { | 1090 | be32_to_cpu(dent->de_hash) < divider) { |
1053 | struct qstr str; | 1091 | struct qstr str; |
1092 | void *ptr = ((char *)dent - obh->b_data) + nbh->b_data; | ||
1054 | str.name = (char*)(dent+1); | 1093 | str.name = (char*)(dent+1); |
1055 | str.len = be16_to_cpu(dent->de_name_len); | 1094 | str.len = be16_to_cpu(dent->de_name_len); |
1056 | str.hash = be32_to_cpu(dent->de_hash); | 1095 | str.hash = be32_to_cpu(dent->de_hash); |
1057 | new = gfs2_dirent_alloc(inode, nbh, &str); | 1096 | new = gfs2_dirent_split_alloc(inode, nbh, &str, ptr); |
1058 | if (IS_ERR(new)) { | 1097 | if (IS_ERR(new)) { |
1059 | error = PTR_ERR(new); | 1098 | error = PTR_ERR(new); |
1060 | break; | 1099 | break; |
@@ -1186,10 +1225,10 @@ static int compare_dents(const void *a, const void *b) | |||
1186 | int ret = 0; | 1225 | int ret = 0; |
1187 | 1226 | ||
1188 | dent_a = *(const struct gfs2_dirent **)a; | 1227 | dent_a = *(const struct gfs2_dirent **)a; |
1189 | hash_a = be32_to_cpu(dent_a->de_hash); | 1228 | hash_a = dent_a->de_cookie; |
1190 | 1229 | ||
1191 | dent_b = *(const struct gfs2_dirent **)b; | 1230 | dent_b = *(const struct gfs2_dirent **)b; |
1192 | hash_b = be32_to_cpu(dent_b->de_hash); | 1231 | hash_b = dent_b->de_cookie; |
1193 | 1232 | ||
1194 | if (hash_a > hash_b) | 1233 | if (hash_a > hash_b) |
1195 | ret = 1; | 1234 | ret = 1; |
@@ -1227,19 +1266,20 @@ static int compare_dents(const void *a, const void *b) | |||
1227 | */ | 1266 | */ |
1228 | 1267 | ||
1229 | static int do_filldir_main(struct gfs2_inode *dip, struct dir_context *ctx, | 1268 | static int do_filldir_main(struct gfs2_inode *dip, struct dir_context *ctx, |
1230 | const struct gfs2_dirent **darr, u32 entries, | 1269 | struct gfs2_dirent **darr, u32 entries, |
1231 | int *copied) | 1270 | u32 sort_start, int *copied) |
1232 | { | 1271 | { |
1233 | const struct gfs2_dirent *dent, *dent_next; | 1272 | const struct gfs2_dirent *dent, *dent_next; |
1234 | u64 off, off_next; | 1273 | u64 off, off_next; |
1235 | unsigned int x, y; | 1274 | unsigned int x, y; |
1236 | int run = 0; | 1275 | int run = 0; |
1237 | 1276 | ||
1238 | sort(darr, entries, sizeof(struct gfs2_dirent *), compare_dents, NULL); | 1277 | if (sort_start < entries) |
1278 | sort(&darr[sort_start], entries - sort_start, | ||
1279 | sizeof(struct gfs2_dirent *), compare_dents, NULL); | ||
1239 | 1280 | ||
1240 | dent_next = darr[0]; | 1281 | dent_next = darr[0]; |
1241 | off_next = be32_to_cpu(dent_next->de_hash); | 1282 | off_next = dent_next->de_cookie; |
1242 | off_next = gfs2_disk_hash2offset(off_next); | ||
1243 | 1283 | ||
1244 | for (x = 0, y = 1; x < entries; x++, y++) { | 1284 | for (x = 0, y = 1; x < entries; x++, y++) { |
1245 | dent = dent_next; | 1285 | dent = dent_next; |
@@ -1247,8 +1287,7 @@ static int do_filldir_main(struct gfs2_inode *dip, struct dir_context *ctx, | |||
1247 | 1287 | ||
1248 | if (y < entries) { | 1288 | if (y < entries) { |
1249 | dent_next = darr[y]; | 1289 | dent_next = darr[y]; |
1250 | off_next = be32_to_cpu(dent_next->de_hash); | 1290 | off_next = dent_next->de_cookie; |
1251 | off_next = gfs2_disk_hash2offset(off_next); | ||
1252 | 1291 | ||
1253 | if (off < ctx->pos) | 1292 | if (off < ctx->pos) |
1254 | continue; | 1293 | continue; |
@@ -1295,6 +1334,40 @@ static void *gfs2_alloc_sort_buffer(unsigned size) | |||
1295 | return ptr; | 1334 | return ptr; |
1296 | } | 1335 | } |
1297 | 1336 | ||
1337 | |||
1338 | static int gfs2_set_cookies(struct gfs2_sbd *sdp, struct buffer_head *bh, | ||
1339 | unsigned leaf_nr, struct gfs2_dirent **darr, | ||
1340 | unsigned entries) | ||
1341 | { | ||
1342 | int sort_id = -1; | ||
1343 | int i; | ||
1344 | |||
1345 | for (i = 0; i < entries; i++) { | ||
1346 | unsigned offset; | ||
1347 | |||
1348 | darr[i]->de_cookie = be32_to_cpu(darr[i]->de_hash); | ||
1349 | darr[i]->de_cookie = gfs2_disk_hash2offset(darr[i]->de_cookie); | ||
1350 | |||
1351 | if (!sdp->sd_args.ar_loccookie) | ||
1352 | continue; | ||
1353 | offset = (char *)(darr[i]) - | ||
1354 | (bh->b_data + gfs2_dirent_offset(bh->b_data)); | ||
1355 | offset /= GFS2_MIN_DIRENT_SIZE; | ||
1356 | offset += leaf_nr * sdp->sd_max_dents_per_leaf; | ||
1357 | if (offset >= GFS2_USE_HASH_FLAG || | ||
1358 | leaf_nr >= GFS2_USE_HASH_FLAG) { | ||
1359 | darr[i]->de_cookie |= GFS2_USE_HASH_FLAG; | ||
1360 | if (sort_id < 0) | ||
1361 | sort_id = i; | ||
1362 | continue; | ||
1363 | } | ||
1364 | darr[i]->de_cookie &= GFS2_HASH_INDEX_MASK; | ||
1365 | darr[i]->de_cookie |= offset; | ||
1366 | } | ||
1367 | return sort_id; | ||
1368 | } | ||
1369 | |||
1370 | |||
1298 | static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, | 1371 | static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, |
1299 | int *copied, unsigned *depth, | 1372 | int *copied, unsigned *depth, |
1300 | u64 leaf_no) | 1373 | u64 leaf_no) |
@@ -1304,12 +1377,11 @@ static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, | |||
1304 | struct buffer_head *bh; | 1377 | struct buffer_head *bh; |
1305 | struct gfs2_leaf *lf; | 1378 | struct gfs2_leaf *lf; |
1306 | unsigned entries = 0, entries2 = 0; | 1379 | unsigned entries = 0, entries2 = 0; |
1307 | unsigned leaves = 0; | 1380 | unsigned leaves = 0, leaf = 0, offset, sort_offset; |
1308 | const struct gfs2_dirent **darr, *dent; | 1381 | struct gfs2_dirent **darr, *dent; |
1309 | struct dirent_gather g; | 1382 | struct dirent_gather g; |
1310 | struct buffer_head **larr; | 1383 | struct buffer_head **larr; |
1311 | int leaf = 0; | 1384 | int error, i, need_sort = 0, sort_id; |
1312 | int error, i; | ||
1313 | u64 lfn = leaf_no; | 1385 | u64 lfn = leaf_no; |
1314 | 1386 | ||
1315 | do { | 1387 | do { |
@@ -1325,6 +1397,11 @@ static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, | |||
1325 | brelse(bh); | 1397 | brelse(bh); |
1326 | } while(lfn); | 1398 | } while(lfn); |
1327 | 1399 | ||
1400 | if (*depth < GFS2_DIR_MAX_DEPTH || !sdp->sd_args.ar_loccookie) { | ||
1401 | need_sort = 1; | ||
1402 | sort_offset = 0; | ||
1403 | } | ||
1404 | |||
1328 | if (!entries) | 1405 | if (!entries) |
1329 | return 0; | 1406 | return 0; |
1330 | 1407 | ||
@@ -1338,8 +1415,8 @@ static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, | |||
1338 | larr = gfs2_alloc_sort_buffer((leaves + entries + 99) * sizeof(void *)); | 1415 | larr = gfs2_alloc_sort_buffer((leaves + entries + 99) * sizeof(void *)); |
1339 | if (!larr) | 1416 | if (!larr) |
1340 | goto out; | 1417 | goto out; |
1341 | darr = (const struct gfs2_dirent **)(larr + leaves); | 1418 | darr = (struct gfs2_dirent **)(larr + leaves); |
1342 | g.pdent = darr; | 1419 | g.pdent = (const struct gfs2_dirent **)darr; |
1343 | g.offset = 0; | 1420 | g.offset = 0; |
1344 | lfn = leaf_no; | 1421 | lfn = leaf_no; |
1345 | 1422 | ||
@@ -1350,6 +1427,7 @@ static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, | |||
1350 | lf = (struct gfs2_leaf *)bh->b_data; | 1427 | lf = (struct gfs2_leaf *)bh->b_data; |
1351 | lfn = be64_to_cpu(lf->lf_next); | 1428 | lfn = be64_to_cpu(lf->lf_next); |
1352 | if (lf->lf_entries) { | 1429 | if (lf->lf_entries) { |
1430 | offset = g.offset; | ||
1353 | entries2 += be16_to_cpu(lf->lf_entries); | 1431 | entries2 += be16_to_cpu(lf->lf_entries); |
1354 | dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, | 1432 | dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, |
1355 | gfs2_dirent_gather, NULL, &g); | 1433 | gfs2_dirent_gather, NULL, &g); |
@@ -1367,17 +1445,26 @@ static int gfs2_dir_read_leaf(struct inode *inode, struct dir_context *ctx, | |||
1367 | goto out_free; | 1445 | goto out_free; |
1368 | } | 1446 | } |
1369 | error = 0; | 1447 | error = 0; |
1448 | sort_id = gfs2_set_cookies(sdp, bh, leaf, &darr[offset], | ||
1449 | be16_to_cpu(lf->lf_entries)); | ||
1450 | if (!need_sort && sort_id >= 0) { | ||
1451 | need_sort = 1; | ||
1452 | sort_offset = offset + sort_id; | ||
1453 | } | ||
1370 | larr[leaf++] = bh; | 1454 | larr[leaf++] = bh; |
1371 | } else { | 1455 | } else { |
1456 | larr[leaf++] = NULL; | ||
1372 | brelse(bh); | 1457 | brelse(bh); |
1373 | } | 1458 | } |
1374 | } while(lfn); | 1459 | } while(lfn); |
1375 | 1460 | ||
1376 | BUG_ON(entries2 != entries); | 1461 | BUG_ON(entries2 != entries); |
1377 | error = do_filldir_main(ip, ctx, darr, entries, copied); | 1462 | error = do_filldir_main(ip, ctx, darr, entries, need_sort ? |
1463 | sort_offset : entries, copied); | ||
1378 | out_free: | 1464 | out_free: |
1379 | for(i = 0; i < leaf; i++) | 1465 | for(i = 0; i < leaf; i++) |
1380 | brelse(larr[i]); | 1466 | if (larr[i]) |
1467 | brelse(larr[i]); | ||
1381 | kvfree(larr); | 1468 | kvfree(larr); |
1382 | out: | 1469 | out: |
1383 | return error; | 1470 | return error; |
@@ -1483,7 +1570,7 @@ int gfs2_dir_read(struct inode *inode, struct dir_context *ctx, | |||
1483 | struct gfs2_inode *dip = GFS2_I(inode); | 1570 | struct gfs2_inode *dip = GFS2_I(inode); |
1484 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 1571 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
1485 | struct dirent_gather g; | 1572 | struct dirent_gather g; |
1486 | const struct gfs2_dirent **darr, *dent; | 1573 | struct gfs2_dirent **darr, *dent; |
1487 | struct buffer_head *dibh; | 1574 | struct buffer_head *dibh; |
1488 | int copied = 0; | 1575 | int copied = 0; |
1489 | int error; | 1576 | int error; |
@@ -1507,7 +1594,7 @@ int gfs2_dir_read(struct inode *inode, struct dir_context *ctx, | |||
1507 | /* 96 is max number of dirents which can be stuffed into an inode */ | 1594 | /* 96 is max number of dirents which can be stuffed into an inode */ |
1508 | darr = kmalloc(96 * sizeof(struct gfs2_dirent *), GFP_NOFS); | 1595 | darr = kmalloc(96 * sizeof(struct gfs2_dirent *), GFP_NOFS); |
1509 | if (darr) { | 1596 | if (darr) { |
1510 | g.pdent = darr; | 1597 | g.pdent = (const struct gfs2_dirent **)darr; |
1511 | g.offset = 0; | 1598 | g.offset = 0; |
1512 | dent = gfs2_dirent_scan(inode, dibh->b_data, dibh->b_size, | 1599 | dent = gfs2_dirent_scan(inode, dibh->b_data, dibh->b_size, |
1513 | gfs2_dirent_gather, NULL, &g); | 1600 | gfs2_dirent_gather, NULL, &g); |
@@ -1524,8 +1611,9 @@ int gfs2_dir_read(struct inode *inode, struct dir_context *ctx, | |||
1524 | error = -EIO; | 1611 | error = -EIO; |
1525 | goto out; | 1612 | goto out; |
1526 | } | 1613 | } |
1614 | gfs2_set_cookies(sdp, dibh, 0, darr, dip->i_entries); | ||
1527 | error = do_filldir_main(dip, ctx, darr, | 1615 | error = do_filldir_main(dip, ctx, darr, |
1528 | dip->i_entries, &copied); | 1616 | dip->i_entries, 0, &copied); |
1529 | out: | 1617 | out: |
1530 | kfree(darr); | 1618 | kfree(darr); |
1531 | } | 1619 | } |
@@ -1560,15 +1648,22 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name, | |||
1560 | 1648 | ||
1561 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); | 1649 | dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); |
1562 | if (dent) { | 1650 | if (dent) { |
1651 | struct inode *inode; | ||
1652 | u16 rahead; | ||
1653 | |||
1563 | if (IS_ERR(dent)) | 1654 | if (IS_ERR(dent)) |
1564 | return ERR_CAST(dent); | 1655 | return ERR_CAST(dent); |
1565 | dtype = be16_to_cpu(dent->de_type); | 1656 | dtype = be16_to_cpu(dent->de_type); |
1657 | rahead = be16_to_cpu(dent->de_rahead); | ||
1566 | addr = be64_to_cpu(dent->de_inum.no_addr); | 1658 | addr = be64_to_cpu(dent->de_inum.no_addr); |
1567 | formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino); | 1659 | formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino); |
1568 | brelse(bh); | 1660 | brelse(bh); |
1569 | if (fail_on_exist) | 1661 | if (fail_on_exist) |
1570 | return ERR_PTR(-EEXIST); | 1662 | return ERR_PTR(-EEXIST); |
1571 | return gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino, 0); | 1663 | inode = gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino, 0); |
1664 | if (!IS_ERR(inode)) | ||
1665 | GFS2_I(inode)->i_rahead = rahead; | ||
1666 | return inode; | ||
1572 | } | 1667 | } |
1573 | return ERR_PTR(-ENOENT); | 1668 | return ERR_PTR(-ENOENT); |
1574 | } | 1669 | } |
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 5e425469f0c2..7412863cda1e 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
@@ -298,9 +298,9 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr) | |||
298 | gfsflags &= ~GFS2_DIF_TOPDIR; | 298 | gfsflags &= ~GFS2_DIF_TOPDIR; |
299 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) | 299 | if (gfsflags & GFS2_DIF_INHERIT_JDATA) |
300 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); | 300 | gfsflags ^= (GFS2_DIF_JDATA | GFS2_DIF_INHERIT_JDATA); |
301 | return do_gfs2_set_flags(filp, gfsflags, ~0); | 301 | return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_SYSTEM); |
302 | } | 302 | } |
303 | return do_gfs2_set_flags(filp, gfsflags, ~GFS2_DIF_JDATA); | 303 | return do_gfs2_set_flags(filp, gfsflags, ~(GFS2_DIF_SYSTEM | GFS2_DIF_JDATA)); |
304 | } | 304 | } |
305 | 305 | ||
306 | static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 306 | static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
@@ -336,8 +336,8 @@ static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) | |||
336 | size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; | 336 | size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; |
337 | int hint = min_t(size_t, INT_MAX, blks); | 337 | int hint = min_t(size_t, INT_MAX, blks); |
338 | 338 | ||
339 | if (hint > atomic_read(&ip->i_res->rs_sizehint)) | 339 | if (hint > atomic_read(&ip->i_res.rs_sizehint)) |
340 | atomic_set(&ip->i_res->rs_sizehint, hint); | 340 | atomic_set(&ip->i_res.rs_sizehint, hint); |
341 | } | 341 | } |
342 | 342 | ||
343 | /** | 343 | /** |
@@ -397,14 +397,10 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
397 | /* Update file times before taking page lock */ | 397 | /* Update file times before taking page lock */ |
398 | file_update_time(vma->vm_file); | 398 | file_update_time(vma->vm_file); |
399 | 399 | ||
400 | ret = get_write_access(inode); | 400 | ret = gfs2_rsqa_alloc(ip); |
401 | if (ret) | 401 | if (ret) |
402 | goto out; | 402 | goto out; |
403 | 403 | ||
404 | ret = gfs2_rs_alloc(ip); | ||
405 | if (ret) | ||
406 | goto out_write_access; | ||
407 | |||
408 | gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE); | 404 | gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE); |
409 | 405 | ||
410 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 406 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
@@ -486,8 +482,6 @@ out_uninit: | |||
486 | set_page_dirty(page); | 482 | set_page_dirty(page); |
487 | wait_for_stable_page(page); | 483 | wait_for_stable_page(page); |
488 | } | 484 | } |
489 | out_write_access: | ||
490 | put_write_access(inode); | ||
491 | out: | 485 | out: |
492 | sb_end_pagefault(inode->i_sb); | 486 | sb_end_pagefault(inode->i_sb); |
493 | return block_page_mkwrite_return(ret); | 487 | return block_page_mkwrite_return(ret); |
@@ -623,7 +617,7 @@ static int gfs2_release(struct inode *inode, struct file *file) | |||
623 | if (!(file->f_mode & FMODE_WRITE)) | 617 | if (!(file->f_mode & FMODE_WRITE)) |
624 | return 0; | 618 | return 0; |
625 | 619 | ||
626 | gfs2_rs_delete(ip, &inode->i_writecount); | 620 | gfs2_rsqa_delete(ip, &inode->i_writecount); |
627 | return 0; | 621 | return 0; |
628 | } | 622 | } |
629 | 623 | ||
@@ -703,7 +697,7 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from) | |||
703 | struct gfs2_inode *ip = GFS2_I(file_inode(file)); | 697 | struct gfs2_inode *ip = GFS2_I(file_inode(file)); |
704 | int ret; | 698 | int ret; |
705 | 699 | ||
706 | ret = gfs2_rs_alloc(ip); | 700 | ret = gfs2_rsqa_alloc(ip); |
707 | if (ret) | 701 | if (ret) |
708 | return ret; | 702 | return ret; |
709 | 703 | ||
@@ -938,13 +932,14 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t le | |||
938 | if (ret) | 932 | if (ret) |
939 | goto out_unlock; | 933 | goto out_unlock; |
940 | 934 | ||
941 | ret = gfs2_rs_alloc(ip); | 935 | ret = gfs2_rsqa_alloc(ip); |
942 | if (ret) | 936 | if (ret) |
943 | goto out_putw; | 937 | goto out_putw; |
944 | 938 | ||
945 | ret = __gfs2_fallocate(file, mode, offset, len); | 939 | ret = __gfs2_fallocate(file, mode, offset, len); |
946 | if (ret) | 940 | if (ret) |
947 | gfs2_rs_deltree(ip->i_res); | 941 | gfs2_rs_deltree(&ip->i_res); |
942 | |||
948 | out_putw: | 943 | out_putw: |
949 | put_write_access(inode); | 944 | put_write_access(inode); |
950 | out_unlock: | 945 | out_unlock: |
@@ -962,7 +957,7 @@ static ssize_t gfs2_file_splice_write(struct pipe_inode_info *pipe, | |||
962 | int error; | 957 | int error; |
963 | struct gfs2_inode *ip = GFS2_I(out->f_mapping->host); | 958 | struct gfs2_inode *ip = GFS2_I(out->f_mapping->host); |
964 | 959 | ||
965 | error = gfs2_rs_alloc(ip); | 960 | error = gfs2_rsqa_alloc(ip); |
966 | if (error) | 961 | if (error) |
967 | return (ssize_t)error; | 962 | return (ssize_t)error; |
968 | 963 | ||
@@ -1018,7 +1013,7 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) | |||
1018 | struct gfs2_inode *ip = GFS2_I(file_inode(file)); | 1013 | struct gfs2_inode *ip = GFS2_I(file_inode(file)); |
1019 | struct gfs2_glock *gl; | 1014 | struct gfs2_glock *gl; |
1020 | unsigned int state; | 1015 | unsigned int state; |
1021 | int flags; | 1016 | u16 flags; |
1022 | int error = 0; | 1017 | int error = 0; |
1023 | int sleeptime; | 1018 | int sleeptime; |
1024 | 1019 | ||
@@ -1032,7 +1027,10 @@ static int do_flock(struct file *file, int cmd, struct file_lock *fl) | |||
1032 | if (fl_gh->gh_state == state) | 1027 | if (fl_gh->gh_state == state) |
1033 | goto out; | 1028 | goto out; |
1034 | locks_lock_file_wait(file, | 1029 | locks_lock_file_wait(file, |
1035 | &(struct file_lock){.fl_type = F_UNLCK}); | 1030 | &(struct file_lock) { |
1031 | .fl_type = F_UNLCK, | ||
1032 | .fl_flags = FL_FLOCK | ||
1033 | }); | ||
1036 | gfs2_glock_dq(fl_gh); | 1034 | gfs2_glock_dq(fl_gh); |
1037 | gfs2_holder_reinit(state, flags, fl_gh); | 1035 | gfs2_holder_reinit(state, flags, fl_gh); |
1038 | } else { | 1036 | } else { |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 32e74710b1aa..a4ff7b56f5cd 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -446,7 +446,7 @@ __acquires(&gl->gl_lockref.lock) | |||
446 | { | 446 | { |
447 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 447 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
448 | struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; | 448 | struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
449 | unsigned int lck_flags = gh ? gh->gh_flags : 0; | 449 | unsigned int lck_flags = (unsigned int)(gh ? gh->gh_flags : 0); |
450 | int ret; | 450 | int ret; |
451 | 451 | ||
452 | lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | | 452 | lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | |
@@ -750,7 +750,7 @@ again: | |||
750 | * | 750 | * |
751 | */ | 751 | */ |
752 | 752 | ||
753 | void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags, | 753 | void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, u16 flags, |
754 | struct gfs2_holder *gh) | 754 | struct gfs2_holder *gh) |
755 | { | 755 | { |
756 | INIT_LIST_HEAD(&gh->gh_list); | 756 | INIT_LIST_HEAD(&gh->gh_list); |
@@ -774,7 +774,7 @@ void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, unsigned flags, | |||
774 | * | 774 | * |
775 | */ | 775 | */ |
776 | 776 | ||
777 | void gfs2_holder_reinit(unsigned int state, unsigned flags, struct gfs2_holder *gh) | 777 | void gfs2_holder_reinit(unsigned int state, u16 flags, struct gfs2_holder *gh) |
778 | { | 778 | { |
779 | gh->gh_state = state; | 779 | gh->gh_state = state; |
780 | gh->gh_flags = flags; | 780 | gh->gh_flags = flags; |
@@ -1080,7 +1080,7 @@ void gfs2_glock_dq_uninit(struct gfs2_holder *gh) | |||
1080 | 1080 | ||
1081 | int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, | 1081 | int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, |
1082 | const struct gfs2_glock_operations *glops, | 1082 | const struct gfs2_glock_operations *glops, |
1083 | unsigned int state, int flags, struct gfs2_holder *gh) | 1083 | unsigned int state, u16 flags, struct gfs2_holder *gh) |
1084 | { | 1084 | { |
1085 | struct gfs2_glock *gl; | 1085 | struct gfs2_glock *gl; |
1086 | int error; | 1086 | int error; |
@@ -1417,14 +1417,14 @@ static struct shrinker glock_shrinker = { | |||
1417 | static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp) | 1417 | static void glock_hash_walk(glock_examiner examiner, const struct gfs2_sbd *sdp) |
1418 | { | 1418 | { |
1419 | struct gfs2_glock *gl; | 1419 | struct gfs2_glock *gl; |
1420 | struct rhash_head *pos, *next; | 1420 | struct rhash_head *pos; |
1421 | const struct bucket_table *tbl; | 1421 | const struct bucket_table *tbl; |
1422 | int i; | 1422 | int i; |
1423 | 1423 | ||
1424 | rcu_read_lock(); | 1424 | rcu_read_lock(); |
1425 | tbl = rht_dereference_rcu(gl_hash_table.tbl, &gl_hash_table); | 1425 | tbl = rht_dereference_rcu(gl_hash_table.tbl, &gl_hash_table); |
1426 | for (i = 0; i < tbl->size; i++) { | 1426 | for (i = 0; i < tbl->size; i++) { |
1427 | rht_for_each_entry_safe(gl, pos, next, tbl, i, gl_node) { | 1427 | rht_for_each_entry_rcu(gl, pos, tbl, i, gl_node) { |
1428 | if ((gl->gl_name.ln_sbd == sdp) && | 1428 | if ((gl->gl_name.ln_sbd == sdp) && |
1429 | lockref_get_not_dead(&gl->gl_lockref)) | 1429 | lockref_get_not_dead(&gl->gl_lockref)) |
1430 | examiner(gl); | 1430 | examiner(gl); |
@@ -1506,7 +1506,9 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) | |||
1506 | flush_workqueue(glock_workqueue); | 1506 | flush_workqueue(glock_workqueue); |
1507 | glock_hash_walk(clear_glock, sdp); | 1507 | glock_hash_walk(clear_glock, sdp); |
1508 | flush_workqueue(glock_workqueue); | 1508 | flush_workqueue(glock_workqueue); |
1509 | wait_event(sdp->sd_glock_wait, atomic_read(&sdp->sd_glock_disposal) == 0); | 1509 | wait_event_timeout(sdp->sd_glock_wait, |
1510 | atomic_read(&sdp->sd_glock_disposal) == 0, | ||
1511 | HZ * 600); | ||
1510 | glock_hash_walk(dump_glock_func, sdp); | 1512 | glock_hash_walk(dump_glock_func, sdp); |
1511 | } | 1513 | } |
1512 | 1514 | ||
@@ -1539,7 +1541,7 @@ static const char *state2str(unsigned state) | |||
1539 | return "??"; | 1541 | return "??"; |
1540 | } | 1542 | } |
1541 | 1543 | ||
1542 | static const char *hflags2str(char *buf, unsigned flags, unsigned long iflags) | 1544 | static const char *hflags2str(char *buf, u16 flags, unsigned long iflags) |
1543 | { | 1545 | { |
1544 | char *p = buf; | 1546 | char *p = buf; |
1545 | if (flags & LM_FLAG_TRY) | 1547 | if (flags & LM_FLAG_TRY) |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index f7cdaa8b4c83..46ab67fc16da 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -79,15 +79,15 @@ enum { | |||
79 | * requested had acquired and released the lock. | 79 | * requested had acquired and released the lock. |
80 | */ | 80 | */ |
81 | 81 | ||
82 | #define LM_FLAG_TRY 0x00000001 | 82 | #define LM_FLAG_TRY 0x0001 |
83 | #define LM_FLAG_TRY_1CB 0x00000002 | 83 | #define LM_FLAG_TRY_1CB 0x0002 |
84 | #define LM_FLAG_NOEXP 0x00000004 | 84 | #define LM_FLAG_NOEXP 0x0004 |
85 | #define LM_FLAG_ANY 0x00000008 | 85 | #define LM_FLAG_ANY 0x0008 |
86 | #define LM_FLAG_PRIORITY 0x00000010 | 86 | #define LM_FLAG_PRIORITY 0x0010 |
87 | #define GL_ASYNC 0x00000040 | 87 | #define GL_ASYNC 0x0040 |
88 | #define GL_EXACT 0x00000080 | 88 | #define GL_EXACT 0x0080 |
89 | #define GL_SKIP 0x00000100 | 89 | #define GL_SKIP 0x0100 |
90 | #define GL_NOCACHE 0x00000400 | 90 | #define GL_NOCACHE 0x0400 |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * lm_async_cb return flags | 93 | * lm_async_cb return flags |
@@ -183,8 +183,8 @@ extern int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, | |||
183 | int create, struct gfs2_glock **glp); | 183 | int create, struct gfs2_glock **glp); |
184 | extern void gfs2_glock_put(struct gfs2_glock *gl); | 184 | extern void gfs2_glock_put(struct gfs2_glock *gl); |
185 | extern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, | 185 | extern void gfs2_holder_init(struct gfs2_glock *gl, unsigned int state, |
186 | unsigned flags, struct gfs2_holder *gh); | 186 | u16 flags, struct gfs2_holder *gh); |
187 | extern void gfs2_holder_reinit(unsigned int state, unsigned flags, | 187 | extern void gfs2_holder_reinit(unsigned int state, u16 flags, |
188 | struct gfs2_holder *gh); | 188 | struct gfs2_holder *gh); |
189 | extern void gfs2_holder_uninit(struct gfs2_holder *gh); | 189 | extern void gfs2_holder_uninit(struct gfs2_holder *gh); |
190 | extern int gfs2_glock_nq(struct gfs2_holder *gh); | 190 | extern int gfs2_glock_nq(struct gfs2_holder *gh); |
@@ -195,7 +195,7 @@ extern void gfs2_glock_dq_wait(struct gfs2_holder *gh); | |||
195 | extern void gfs2_glock_dq_uninit(struct gfs2_holder *gh); | 195 | extern void gfs2_glock_dq_uninit(struct gfs2_holder *gh); |
196 | extern int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, | 196 | extern int gfs2_glock_nq_num(struct gfs2_sbd *sdp, u64 number, |
197 | const struct gfs2_glock_operations *glops, | 197 | const struct gfs2_glock_operations *glops, |
198 | unsigned int state, int flags, | 198 | unsigned int state, u16 flags, |
199 | struct gfs2_holder *gh); | 199 | struct gfs2_holder *gh); |
200 | extern int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); | 200 | extern int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs); |
201 | extern void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); | 201 | extern void gfs2_glock_dq_m(unsigned int num_gh, struct gfs2_holder *ghs); |
@@ -215,7 +215,7 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...); | |||
215 | */ | 215 | */ |
216 | 216 | ||
217 | static inline int gfs2_glock_nq_init(struct gfs2_glock *gl, | 217 | static inline int gfs2_glock_nq_init(struct gfs2_glock *gl, |
218 | unsigned int state, int flags, | 218 | unsigned int state, u16 flags, |
219 | struct gfs2_holder *gh) | 219 | struct gfs2_holder *gh) |
220 | { | 220 | { |
221 | int error; | 221 | int error; |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index de7b4f97ac75..845fb09cc606 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -259,8 +259,8 @@ struct gfs2_holder { | |||
259 | 259 | ||
260 | struct gfs2_glock *gh_gl; | 260 | struct gfs2_glock *gh_gl; |
261 | struct pid *gh_owner_pid; | 261 | struct pid *gh_owner_pid; |
262 | unsigned int gh_state; | 262 | u16 gh_flags; |
263 | unsigned gh_flags; | 263 | u16 gh_state; |
264 | 264 | ||
265 | int gh_error; | 265 | int gh_error; |
266 | unsigned long gh_iflags; /* HIF_... */ | 266 | unsigned long gh_iflags; /* HIF_... */ |
@@ -270,6 +270,13 @@ struct gfs2_holder { | |||
270 | /* Number of quota types we support */ | 270 | /* Number of quota types we support */ |
271 | #define GFS2_MAXQUOTAS 2 | 271 | #define GFS2_MAXQUOTAS 2 |
272 | 272 | ||
273 | struct gfs2_qadata { /* quota allocation data */ | ||
274 | /* Quota stuff */ | ||
275 | struct gfs2_quota_data *qa_qd[2 * GFS2_MAXQUOTAS]; | ||
276 | struct gfs2_holder qa_qd_ghs[2 * GFS2_MAXQUOTAS]; | ||
277 | unsigned int qa_qd_num; | ||
278 | }; | ||
279 | |||
273 | /* Resource group multi-block reservation, in order of appearance: | 280 | /* Resource group multi-block reservation, in order of appearance: |
274 | 281 | ||
275 | Step 1. Function prepares to write, allocates a mb, sets the size hint. | 282 | Step 1. Function prepares to write, allocates a mb, sets the size hint. |
@@ -288,11 +295,6 @@ struct gfs2_blkreserv { | |||
288 | struct gfs2_rbm rs_rbm; /* Start of reservation */ | 295 | struct gfs2_rbm rs_rbm; /* Start of reservation */ |
289 | u32 rs_free; /* how many blocks are still free */ | 296 | u32 rs_free; /* how many blocks are still free */ |
290 | u64 rs_inum; /* Inode number for reservation */ | 297 | u64 rs_inum; /* Inode number for reservation */ |
291 | |||
292 | /* ancillary quota stuff */ | ||
293 | struct gfs2_quota_data *rs_qa_qd[2 * GFS2_MAXQUOTAS]; | ||
294 | struct gfs2_holder rs_qa_qd_ghs[2 * GFS2_MAXQUOTAS]; | ||
295 | unsigned int rs_qa_qd_num; | ||
296 | }; | 298 | }; |
297 | 299 | ||
298 | /* | 300 | /* |
@@ -391,7 +393,8 @@ struct gfs2_inode { | |||
391 | struct gfs2_glock *i_gl; /* Move into i_gh? */ | 393 | struct gfs2_glock *i_gl; /* Move into i_gh? */ |
392 | struct gfs2_holder i_iopen_gh; | 394 | struct gfs2_holder i_iopen_gh; |
393 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ | 395 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ |
394 | struct gfs2_blkreserv *i_res; /* rgrp multi-block reservation */ | 396 | struct gfs2_qadata *i_qadata; /* quota allocation data */ |
397 | struct gfs2_blkreserv i_res; /* rgrp multi-block reservation */ | ||
395 | struct gfs2_rgrpd *i_rgd; | 398 | struct gfs2_rgrpd *i_rgd; |
396 | u64 i_goal; /* goal block for allocations */ | 399 | u64 i_goal; /* goal block for allocations */ |
397 | struct rw_semaphore i_rw_mutex; | 400 | struct rw_semaphore i_rw_mutex; |
@@ -402,6 +405,7 @@ struct gfs2_inode { | |||
402 | u32 i_diskflags; | 405 | u32 i_diskflags; |
403 | u8 i_height; | 406 | u8 i_height; |
404 | u8 i_depth; | 407 | u8 i_depth; |
408 | u16 i_rahead; | ||
405 | }; | 409 | }; |
406 | 410 | ||
407 | /* | 411 | /* |
@@ -558,6 +562,8 @@ struct gfs2_args { | |||
558 | unsigned int ar_errors:2; /* errors=withdraw | panic */ | 562 | unsigned int ar_errors:2; /* errors=withdraw | panic */ |
559 | unsigned int ar_nobarrier:1; /* do not send barriers */ | 563 | unsigned int ar_nobarrier:1; /* do not send barriers */ |
560 | unsigned int ar_rgrplvb:1; /* use lvbs for rgrp info */ | 564 | unsigned int ar_rgrplvb:1; /* use lvbs for rgrp info */ |
565 | unsigned int ar_loccookie:1; /* use location based readdir | ||
566 | cookies */ | ||
561 | int ar_commit; /* Commit interval */ | 567 | int ar_commit; /* Commit interval */ |
562 | int ar_statfs_quantum; /* The fast statfs interval */ | 568 | int ar_statfs_quantum; /* The fast statfs interval */ |
563 | int ar_quota_quantum; /* The quota interval */ | 569 | int ar_quota_quantum; /* The quota interval */ |
@@ -685,6 +691,7 @@ struct gfs2_sbd { | |||
685 | u64 sd_heightsize[GFS2_MAX_META_HEIGHT + 1]; | 691 | u64 sd_heightsize[GFS2_MAX_META_HEIGHT + 1]; |
686 | u32 sd_max_jheight; /* Max height of journaled file's meta tree */ | 692 | u32 sd_max_jheight; /* Max height of journaled file's meta tree */ |
687 | u64 sd_jheightsize[GFS2_MAX_META_HEIGHT + 1]; | 693 | u64 sd_jheightsize[GFS2_MAX_META_HEIGHT + 1]; |
694 | u32 sd_max_dents_per_leaf; /* Max number of dirents in a leaf block */ | ||
688 | 695 | ||
689 | struct gfs2_args sd_args; /* Mount arguments */ | 696 | struct gfs2_args sd_args; /* Mount arguments */ |
690 | struct gfs2_tune sd_tune; /* Filesystem tuning structure */ | 697 | struct gfs2_tune sd_tune; /* Filesystem tuning structure */ |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 1bae189f3245..3e94400d587c 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -191,13 +191,13 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, | |||
191 | fail_refresh: | 191 | fail_refresh: |
192 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; | 192 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; |
193 | ip->i_iopen_gh.gh_gl->gl_object = NULL; | 193 | ip->i_iopen_gh.gh_gl->gl_object = NULL; |
194 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 194 | gfs2_glock_dq_wait(&ip->i_iopen_gh); |
195 | gfs2_holder_uninit(&ip->i_iopen_gh); | ||
195 | fail_iopen: | 196 | fail_iopen: |
196 | if (io_gl) | 197 | if (io_gl) |
197 | gfs2_glock_put(io_gl); | 198 | gfs2_glock_put(io_gl); |
198 | fail_put: | 199 | fail_put: |
199 | ip->i_gl->gl_object = NULL; | 200 | ip->i_gl->gl_object = NULL; |
200 | gfs2_glock_put(ip->i_gl); | ||
201 | fail: | 201 | fail: |
202 | iget_failed(inode); | 202 | iget_failed(inode); |
203 | return ERR_PTR(error); | 203 | return ERR_PTR(error); |
@@ -593,7 +593,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
593 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | 593 | struct gfs2_inode *dip = GFS2_I(dir), *ip; |
594 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 594 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
595 | struct gfs2_glock *io_gl; | 595 | struct gfs2_glock *io_gl; |
596 | int error, free_vfs_inode = 0; | 596 | int error, free_vfs_inode = 1; |
597 | u32 aflags = 0; | 597 | u32 aflags = 0; |
598 | unsigned blocks = 1; | 598 | unsigned blocks = 1; |
599 | struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, }; | 599 | struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, }; |
@@ -601,7 +601,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
601 | if (!name->len || name->len > GFS2_FNAMESIZE) | 601 | if (!name->len || name->len > GFS2_FNAMESIZE) |
602 | return -ENAMETOOLONG; | 602 | return -ENAMETOOLONG; |
603 | 603 | ||
604 | error = gfs2_rs_alloc(dip); | 604 | error = gfs2_rsqa_alloc(dip); |
605 | if (error) | 605 | if (error) |
606 | return error; | 606 | return error; |
607 | 607 | ||
@@ -650,10 +650,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
650 | 650 | ||
651 | error = posix_acl_create(dir, &mode, &default_acl, &acl); | 651 | error = posix_acl_create(dir, &mode, &default_acl, &acl); |
652 | if (error) | 652 | if (error) |
653 | goto fail_free_vfs_inode; | 653 | goto fail_gunlock; |
654 | 654 | ||
655 | ip = GFS2_I(inode); | 655 | ip = GFS2_I(inode); |
656 | error = gfs2_rs_alloc(ip); | 656 | error = gfs2_rsqa_alloc(ip); |
657 | if (error) | 657 | if (error) |
658 | goto fail_free_acls; | 658 | goto fail_free_acls; |
659 | 659 | ||
@@ -685,6 +685,11 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
685 | ip->i_entries = 2; | 685 | ip->i_entries = 2; |
686 | break; | 686 | break; |
687 | } | 687 | } |
688 | |||
689 | /* Force SYSTEM flag on all files and subdirs of a SYSTEM directory */ | ||
690 | if (dip->i_diskflags & GFS2_DIF_SYSTEM) | ||
691 | ip->i_diskflags |= GFS2_DIF_SYSTEM; | ||
692 | |||
688 | gfs2_set_inode_flags(inode); | 693 | gfs2_set_inode_flags(inode); |
689 | 694 | ||
690 | if ((GFS2_I(d_inode(sdp->sd_root_dir)) == dip) || | 695 | if ((GFS2_I(d_inode(sdp->sd_root_dir)) == dip) || |
@@ -733,6 +738,9 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
733 | gfs2_set_iop(inode); | 738 | gfs2_set_iop(inode); |
734 | insert_inode_hash(inode); | 739 | insert_inode_hash(inode); |
735 | 740 | ||
741 | free_vfs_inode = 0; /* After this point, the inode is no longer | ||
742 | considered free. Any failures need to undo | ||
743 | the gfs2 structures. */ | ||
736 | if (default_acl) { | 744 | if (default_acl) { |
737 | error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); | 745 | error = gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT); |
738 | posix_acl_release(default_acl); | 746 | posix_acl_release(default_acl); |
@@ -766,24 +774,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, | |||
766 | return error; | 774 | return error; |
767 | 775 | ||
768 | fail_gunlock3: | 776 | fail_gunlock3: |
769 | gfs2_glock_dq_uninit(ghs + 1); | 777 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
770 | if (ip->i_gl) | 778 | gfs2_glock_put(io_gl); |
771 | gfs2_glock_put(ip->i_gl); | ||
772 | goto fail_gunlock; | ||
773 | |||
774 | fail_gunlock2: | 779 | fail_gunlock2: |
775 | gfs2_glock_dq_uninit(ghs + 1); | 780 | gfs2_glock_dq_uninit(ghs + 1); |
776 | fail_free_inode: | 781 | fail_free_inode: |
777 | if (ip->i_gl) | 782 | if (ip->i_gl) |
778 | gfs2_glock_put(ip->i_gl); | 783 | gfs2_glock_put(ip->i_gl); |
779 | gfs2_rs_delete(ip, NULL); | 784 | gfs2_rsqa_delete(ip, NULL); |
780 | fail_free_acls: | 785 | fail_free_acls: |
781 | if (default_acl) | 786 | if (default_acl) |
782 | posix_acl_release(default_acl); | 787 | posix_acl_release(default_acl); |
783 | if (acl) | 788 | if (acl) |
784 | posix_acl_release(acl); | 789 | posix_acl_release(acl); |
785 | fail_free_vfs_inode: | ||
786 | free_vfs_inode = 1; | ||
787 | fail_gunlock: | 790 | fail_gunlock: |
788 | gfs2_dir_no_add(&da); | 791 | gfs2_dir_no_add(&da); |
789 | gfs2_glock_dq_uninit(ghs); | 792 | gfs2_glock_dq_uninit(ghs); |
@@ -898,7 +901,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
898 | if (S_ISDIR(inode->i_mode)) | 901 | if (S_ISDIR(inode->i_mode)) |
899 | return -EPERM; | 902 | return -EPERM; |
900 | 903 | ||
901 | error = gfs2_rs_alloc(dip); | 904 | error = gfs2_rsqa_alloc(dip); |
902 | if (error) | 905 | if (error) |
903 | return error; | 906 | return error; |
904 | 907 | ||
@@ -1371,7 +1374,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
1371 | if (error) | 1374 | if (error) |
1372 | return error; | 1375 | return error; |
1373 | 1376 | ||
1374 | error = gfs2_rs_alloc(ndip); | 1377 | error = gfs2_rsqa_alloc(ndip); |
1375 | if (error) | 1378 | if (error) |
1376 | return error; | 1379 | return error; |
1377 | 1380 | ||
@@ -1860,11 +1863,7 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
1860 | if (!(attr->ia_valid & ATTR_GID) || gid_eq(ogid, ngid)) | 1863 | if (!(attr->ia_valid & ATTR_GID) || gid_eq(ogid, ngid)) |
1861 | ogid = ngid = NO_GID_QUOTA_CHANGE; | 1864 | ogid = ngid = NO_GID_QUOTA_CHANGE; |
1862 | 1865 | ||
1863 | error = get_write_access(inode); | 1866 | error = gfs2_rsqa_alloc(ip); |
1864 | if (error) | ||
1865 | return error; | ||
1866 | |||
1867 | error = gfs2_rs_alloc(ip); | ||
1868 | if (error) | 1867 | if (error) |
1869 | goto out; | 1868 | goto out; |
1870 | 1869 | ||
@@ -1904,7 +1903,6 @@ out_end_trans: | |||
1904 | out_gunlock_q: | 1903 | out_gunlock_q: |
1905 | gfs2_quota_unlock(ip); | 1904 | gfs2_quota_unlock(ip); |
1906 | out: | 1905 | out: |
1907 | put_write_access(inode); | ||
1908 | return error; | 1906 | return error; |
1909 | } | 1907 | } |
1910 | 1908 | ||
@@ -1926,7 +1924,7 @@ static int gfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
1926 | struct gfs2_holder i_gh; | 1924 | struct gfs2_holder i_gh; |
1927 | int error; | 1925 | int error; |
1928 | 1926 | ||
1929 | error = gfs2_rs_alloc(ip); | 1927 | error = gfs2_rsqa_alloc(ip); |
1930 | if (error) | 1928 | if (error) |
1931 | return error; | 1929 | return error; |
1932 | 1930 | ||
@@ -2008,7 +2006,7 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name, | |||
2008 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 2006 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
2009 | ret = gfs2_glock_nq(&gh); | 2007 | ret = gfs2_glock_nq(&gh); |
2010 | if (ret == 0) { | 2008 | if (ret == 0) { |
2011 | ret = gfs2_rs_alloc(ip); | 2009 | ret = gfs2_rsqa_alloc(ip); |
2012 | if (ret == 0) | 2010 | if (ret == 0) |
2013 | ret = generic_setxattr(dentry, name, data, size, flags); | 2011 | ret = generic_setxattr(dentry, name, data, size, flags); |
2014 | gfs2_glock_dq(&gh); | 2012 | gfs2_glock_dq(&gh); |
@@ -2049,7 +2047,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name) | |||
2049 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 2047 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
2050 | ret = gfs2_glock_nq(&gh); | 2048 | ret = gfs2_glock_nq(&gh); |
2051 | if (ret == 0) { | 2049 | if (ret == 0) { |
2052 | ret = gfs2_rs_alloc(ip); | 2050 | ret = gfs2_rsqa_alloc(ip); |
2053 | if (ret == 0) | 2051 | if (ret == 0) |
2054 | ret = generic_removexattr(dentry, name); | 2052 | ret = generic_removexattr(dentry, name); |
2055 | gfs2_glock_dq(&gh); | 2053 | gfs2_glock_dq(&gh); |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 536e7a6252cd..0ff028c15199 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -716,6 +716,9 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, | |||
716 | } | 716 | } |
717 | trace_gfs2_log_flush(sdp, 1); | 717 | trace_gfs2_log_flush(sdp, 1); |
718 | 718 | ||
719 | if (type == SHUTDOWN_FLUSH) | ||
720 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | ||
721 | |||
719 | sdp->sd_log_flush_head = sdp->sd_log_head; | 722 | sdp->sd_log_flush_head = sdp->sd_log_head; |
720 | sdp->sd_log_flush_wrapped = 0; | 723 | sdp->sd_log_flush_wrapped = 0; |
721 | tr = sdp->sd_log_tr; | 724 | tr = sdp->sd_log_tr; |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index fb2b42cf46b5..1d709d496364 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -41,7 +41,9 @@ static void gfs2_init_inode_once(void *foo) | |||
41 | inode_init_once(&ip->i_inode); | 41 | inode_init_once(&ip->i_inode); |
42 | init_rwsem(&ip->i_rw_mutex); | 42 | init_rwsem(&ip->i_rw_mutex); |
43 | INIT_LIST_HEAD(&ip->i_trunc_list); | 43 | INIT_LIST_HEAD(&ip->i_trunc_list); |
44 | ip->i_res = NULL; | 44 | ip->i_qadata = NULL; |
45 | memset(&ip->i_res, 0, sizeof(ip->i_res)); | ||
46 | RB_CLEAR_NODE(&ip->i_res.rs_node); | ||
45 | ip->i_hash_cache = NULL; | 47 | ip->i_hash_cache = NULL; |
46 | } | 48 | } |
47 | 49 | ||
@@ -135,10 +137,10 @@ static int __init init_gfs2_fs(void) | |||
135 | if (!gfs2_quotad_cachep) | 137 | if (!gfs2_quotad_cachep) |
136 | goto fail; | 138 | goto fail; |
137 | 139 | ||
138 | gfs2_rsrv_cachep = kmem_cache_create("gfs2_mblk", | 140 | gfs2_qadata_cachep = kmem_cache_create("gfs2_qadata", |
139 | sizeof(struct gfs2_blkreserv), | 141 | sizeof(struct gfs2_qadata), |
140 | 0, 0, NULL); | 142 | 0, 0, NULL); |
141 | if (!gfs2_rsrv_cachep) | 143 | if (!gfs2_qadata_cachep) |
142 | goto fail; | 144 | goto fail; |
143 | 145 | ||
144 | register_shrinker(&gfs2_qd_shrinker); | 146 | register_shrinker(&gfs2_qd_shrinker); |
@@ -193,8 +195,8 @@ fail_lru: | |||
193 | unregister_shrinker(&gfs2_qd_shrinker); | 195 | unregister_shrinker(&gfs2_qd_shrinker); |
194 | gfs2_glock_exit(); | 196 | gfs2_glock_exit(); |
195 | 197 | ||
196 | if (gfs2_rsrv_cachep) | 198 | if (gfs2_qadata_cachep) |
197 | kmem_cache_destroy(gfs2_rsrv_cachep); | 199 | kmem_cache_destroy(gfs2_qadata_cachep); |
198 | 200 | ||
199 | if (gfs2_quotad_cachep) | 201 | if (gfs2_quotad_cachep) |
200 | kmem_cache_destroy(gfs2_quotad_cachep); | 202 | kmem_cache_destroy(gfs2_quotad_cachep); |
@@ -238,7 +240,7 @@ static void __exit exit_gfs2_fs(void) | |||
238 | rcu_barrier(); | 240 | rcu_barrier(); |
239 | 241 | ||
240 | mempool_destroy(gfs2_page_pool); | 242 | mempool_destroy(gfs2_page_pool); |
241 | kmem_cache_destroy(gfs2_rsrv_cachep); | 243 | kmem_cache_destroy(gfs2_qadata_cachep); |
242 | kmem_cache_destroy(gfs2_quotad_cachep); | 244 | kmem_cache_destroy(gfs2_quotad_cachep); |
243 | kmem_cache_destroy(gfs2_rgrpd_cachep); | 245 | kmem_cache_destroy(gfs2_rgrpd_cachep); |
244 | kmem_cache_destroy(gfs2_bufdata_cachep); | 246 | kmem_cache_destroy(gfs2_bufdata_cachep); |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 0e1d4be5865a..e137d96f1b17 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -187,6 +187,52 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | |||
187 | return bh; | 187 | return bh; |
188 | } | 188 | } |
189 | 189 | ||
190 | static void gfs2_meta_read_endio(struct bio *bio) | ||
191 | { | ||
192 | struct bio_vec *bvec; | ||
193 | int i; | ||
194 | |||
195 | bio_for_each_segment_all(bvec, bio, i) { | ||
196 | struct page *page = bvec->bv_page; | ||
197 | struct buffer_head *bh = page_buffers(page); | ||
198 | unsigned int len = bvec->bv_len; | ||
199 | |||
200 | while (bh_offset(bh) < bvec->bv_offset) | ||
201 | bh = bh->b_this_page; | ||
202 | do { | ||
203 | struct buffer_head *next = bh->b_this_page; | ||
204 | len -= bh->b_size; | ||
205 | bh->b_end_io(bh, !bio->bi_error); | ||
206 | bh = next; | ||
207 | } while (bh && len); | ||
208 | } | ||
209 | bio_put(bio); | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * Submit several consecutive buffer head I/O requests as a single bio I/O | ||
214 | * request. (See submit_bh_wbc.) | ||
215 | */ | ||
216 | static void gfs2_submit_bhs(int rw, struct buffer_head *bhs[], int num) | ||
217 | { | ||
218 | struct buffer_head *bh = bhs[0]; | ||
219 | struct bio *bio; | ||
220 | int i; | ||
221 | |||
222 | if (!num) | ||
223 | return; | ||
224 | |||
225 | bio = bio_alloc(GFP_NOIO, num); | ||
226 | bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); | ||
227 | bio->bi_bdev = bh->b_bdev; | ||
228 | for (i = 0; i < num; i++) { | ||
229 | bh = bhs[i]; | ||
230 | bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh)); | ||
231 | } | ||
232 | bio->bi_end_io = gfs2_meta_read_endio; | ||
233 | submit_bio(rw, bio); | ||
234 | } | ||
235 | |||
190 | /** | 236 | /** |
191 | * gfs2_meta_read - Read a block from disk | 237 | * gfs2_meta_read - Read a block from disk |
192 | * @gl: The glock covering the block | 238 | * @gl: The glock covering the block |
@@ -198,10 +244,11 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | |||
198 | */ | 244 | */ |
199 | 245 | ||
200 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | 246 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, |
201 | struct buffer_head **bhp) | 247 | int rahead, struct buffer_head **bhp) |
202 | { | 248 | { |
203 | struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; | 249 | struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; |
204 | struct buffer_head *bh; | 250 | struct buffer_head *bh, *bhs[2]; |
251 | int num = 0; | ||
205 | 252 | ||
206 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { | 253 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { |
207 | *bhp = NULL; | 254 | *bhp = NULL; |
@@ -213,14 +260,31 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | |||
213 | lock_buffer(bh); | 260 | lock_buffer(bh); |
214 | if (buffer_uptodate(bh)) { | 261 | if (buffer_uptodate(bh)) { |
215 | unlock_buffer(bh); | 262 | unlock_buffer(bh); |
216 | return 0; | 263 | flags &= ~DIO_WAIT; |
264 | } else { | ||
265 | bh->b_end_io = end_buffer_read_sync; | ||
266 | get_bh(bh); | ||
267 | bhs[num++] = bh; | ||
217 | } | 268 | } |
218 | bh->b_end_io = end_buffer_read_sync; | 269 | |
219 | get_bh(bh); | 270 | if (rahead) { |
220 | submit_bh(READ_SYNC | REQ_META | REQ_PRIO, bh); | 271 | bh = gfs2_getbuf(gl, blkno + 1, CREATE); |
272 | |||
273 | lock_buffer(bh); | ||
274 | if (buffer_uptodate(bh)) { | ||
275 | unlock_buffer(bh); | ||
276 | brelse(bh); | ||
277 | } else { | ||
278 | bh->b_end_io = end_buffer_read_sync; | ||
279 | bhs[num++] = bh; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | gfs2_submit_bhs(READ_SYNC | REQ_META | REQ_PRIO, bhs, num); | ||
221 | if (!(flags & DIO_WAIT)) | 284 | if (!(flags & DIO_WAIT)) |
222 | return 0; | 285 | return 0; |
223 | 286 | ||
287 | bh = *bhp; | ||
224 | wait_on_buffer(bh); | 288 | wait_on_buffer(bh); |
225 | if (unlikely(!buffer_uptodate(bh))) { | 289 | if (unlikely(!buffer_uptodate(bh))) { |
226 | struct gfs2_trans *tr = current->journal_info; | 290 | struct gfs2_trans *tr = current->journal_info; |
@@ -341,8 +405,12 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
341 | struct buffer_head *bh; | 405 | struct buffer_head *bh; |
342 | int ret = 0; | 406 | int ret = 0; |
343 | u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; | 407 | u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; |
408 | int rahead = 0; | ||
409 | |||
410 | if (num == ip->i_no_addr) | ||
411 | rahead = ip->i_rahead; | ||
344 | 412 | ||
345 | ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); | 413 | ret = gfs2_meta_read(gl, num, DIO_WAIT, rahead, &bh); |
346 | if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { | 414 | if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { |
347 | brelse(bh); | 415 | brelse(bh); |
348 | ret = -EIO; | 416 | ret = -EIO; |
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index 8ca161567a93..c5086c8af5ed 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h | |||
@@ -53,7 +53,7 @@ static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping) | |||
53 | 53 | ||
54 | extern struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno); | 54 | extern struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno); |
55 | extern int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | 55 | extern int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, |
56 | struct buffer_head **bhp); | 56 | int rahead, struct buffer_head **bhp); |
57 | extern int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh); | 57 | extern int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh); |
58 | extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, | 58 | extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, |
59 | int create); | 59 | int create); |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 001c66641243..dbed9e243ea2 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -352,6 +352,9 @@ static int gfs2_read_sb(struct gfs2_sbd *sdp, int silent) | |||
352 | sdp->sd_jheightsize[x] = ~0; | 352 | sdp->sd_jheightsize[x] = ~0; |
353 | gfs2_assert(sdp, sdp->sd_max_jheight <= GFS2_MAX_META_HEIGHT); | 353 | gfs2_assert(sdp, sdp->sd_max_jheight <= GFS2_MAX_META_HEIGHT); |
354 | 354 | ||
355 | sdp->sd_max_dents_per_leaf = (sdp->sd_sb.sb_bsize - | ||
356 | sizeof(struct gfs2_leaf)) / | ||
357 | GFS2_MIN_DIRENT_SIZE; | ||
355 | return 0; | 358 | return 0; |
356 | } | 359 | } |
357 | 360 | ||
@@ -910,8 +913,7 @@ fail_qc_i: | |||
910 | fail_ut_i: | 913 | fail_ut_i: |
911 | iput(sdp->sd_sc_inode); | 914 | iput(sdp->sd_sc_inode); |
912 | fail: | 915 | fail: |
913 | if (pn) | 916 | iput(pn); |
914 | iput(pn); | ||
915 | return error; | 917 | return error; |
916 | } | 918 | } |
917 | 919 | ||
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 3a31226531ea..be6d9c450b22 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -388,7 +388,7 @@ static int bh_get(struct gfs2_quota_data *qd) | |||
388 | error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0); | 388 | error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0); |
389 | if (error) | 389 | if (error) |
390 | goto fail; | 390 | goto fail; |
391 | error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, &bh); | 391 | error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, 0, &bh); |
392 | if (error) | 392 | if (error) |
393 | goto fail; | 393 | goto fail; |
394 | error = -EIO; | 394 | error = -EIO; |
@@ -527,37 +527,70 @@ static void qdsb_put(struct gfs2_quota_data *qd) | |||
527 | qd_put(qd); | 527 | qd_put(qd); |
528 | } | 528 | } |
529 | 529 | ||
530 | /** | ||
531 | * gfs2_qa_alloc - make sure we have a quota allocations data structure, | ||
532 | * if necessary | ||
533 | * @ip: the inode for this reservation | ||
534 | */ | ||
535 | int gfs2_qa_alloc(struct gfs2_inode *ip) | ||
536 | { | ||
537 | int error = 0; | ||
538 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
539 | |||
540 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | ||
541 | return 0; | ||
542 | |||
543 | down_write(&ip->i_rw_mutex); | ||
544 | if (ip->i_qadata == NULL) { | ||
545 | ip->i_qadata = kmem_cache_zalloc(gfs2_qadata_cachep, GFP_NOFS); | ||
546 | if (!ip->i_qadata) | ||
547 | error = -ENOMEM; | ||
548 | } | ||
549 | up_write(&ip->i_rw_mutex); | ||
550 | return error; | ||
551 | } | ||
552 | |||
553 | void gfs2_qa_delete(struct gfs2_inode *ip, atomic_t *wcount) | ||
554 | { | ||
555 | down_write(&ip->i_rw_mutex); | ||
556 | if (ip->i_qadata && ((wcount == NULL) || (atomic_read(wcount) <= 1))) { | ||
557 | kmem_cache_free(gfs2_qadata_cachep, ip->i_qadata); | ||
558 | ip->i_qadata = NULL; | ||
559 | } | ||
560 | up_write(&ip->i_rw_mutex); | ||
561 | } | ||
562 | |||
530 | int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | 563 | int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) |
531 | { | 564 | { |
532 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 565 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
533 | struct gfs2_quota_data **qd; | 566 | struct gfs2_quota_data **qd; |
534 | int error; | 567 | int error; |
535 | 568 | ||
536 | if (ip->i_res == NULL) { | 569 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
537 | error = gfs2_rs_alloc(ip); | 570 | return 0; |
571 | |||
572 | if (ip->i_qadata == NULL) { | ||
573 | error = gfs2_rsqa_alloc(ip); | ||
538 | if (error) | 574 | if (error) |
539 | return error; | 575 | return error; |
540 | } | 576 | } |
541 | 577 | ||
542 | qd = ip->i_res->rs_qa_qd; | 578 | qd = ip->i_qadata->qa_qd; |
543 | 579 | ||
544 | if (gfs2_assert_warn(sdp, !ip->i_res->rs_qa_qd_num) || | 580 | if (gfs2_assert_warn(sdp, !ip->i_qadata->qa_qd_num) || |
545 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) | 581 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags))) |
546 | return -EIO; | 582 | return -EIO; |
547 | 583 | ||
548 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | ||
549 | return 0; | ||
550 | |||
551 | error = qdsb_get(sdp, make_kqid_uid(ip->i_inode.i_uid), qd); | 584 | error = qdsb_get(sdp, make_kqid_uid(ip->i_inode.i_uid), qd); |
552 | if (error) | 585 | if (error) |
553 | goto out; | 586 | goto out; |
554 | ip->i_res->rs_qa_qd_num++; | 587 | ip->i_qadata->qa_qd_num++; |
555 | qd++; | 588 | qd++; |
556 | 589 | ||
557 | error = qdsb_get(sdp, make_kqid_gid(ip->i_inode.i_gid), qd); | 590 | error = qdsb_get(sdp, make_kqid_gid(ip->i_inode.i_gid), qd); |
558 | if (error) | 591 | if (error) |
559 | goto out; | 592 | goto out; |
560 | ip->i_res->rs_qa_qd_num++; | 593 | ip->i_qadata->qa_qd_num++; |
561 | qd++; | 594 | qd++; |
562 | 595 | ||
563 | if (!uid_eq(uid, NO_UID_QUOTA_CHANGE) && | 596 | if (!uid_eq(uid, NO_UID_QUOTA_CHANGE) && |
@@ -565,7 +598,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
565 | error = qdsb_get(sdp, make_kqid_uid(uid), qd); | 598 | error = qdsb_get(sdp, make_kqid_uid(uid), qd); |
566 | if (error) | 599 | if (error) |
567 | goto out; | 600 | goto out; |
568 | ip->i_res->rs_qa_qd_num++; | 601 | ip->i_qadata->qa_qd_num++; |
569 | qd++; | 602 | qd++; |
570 | } | 603 | } |
571 | 604 | ||
@@ -574,7 +607,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
574 | error = qdsb_get(sdp, make_kqid_gid(gid), qd); | 607 | error = qdsb_get(sdp, make_kqid_gid(gid), qd); |
575 | if (error) | 608 | if (error) |
576 | goto out; | 609 | goto out; |
577 | ip->i_res->rs_qa_qd_num++; | 610 | ip->i_qadata->qa_qd_num++; |
578 | qd++; | 611 | qd++; |
579 | } | 612 | } |
580 | 613 | ||
@@ -587,17 +620,17 @@ out: | |||
587 | void gfs2_quota_unhold(struct gfs2_inode *ip) | 620 | void gfs2_quota_unhold(struct gfs2_inode *ip) |
588 | { | 621 | { |
589 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 622 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
590 | unsigned int x; | 623 | u32 x; |
591 | 624 | ||
592 | if (ip->i_res == NULL) | 625 | if (ip->i_qadata == NULL) |
593 | return; | 626 | return; |
594 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); | 627 | gfs2_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); |
595 | 628 | ||
596 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 629 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
597 | qdsb_put(ip->i_res->rs_qa_qd[x]); | 630 | qdsb_put(ip->i_qadata->qa_qd[x]); |
598 | ip->i_res->rs_qa_qd[x] = NULL; | 631 | ip->i_qadata->qa_qd[x] = NULL; |
599 | } | 632 | } |
600 | ip->i_res->rs_qa_qd_num = 0; | 633 | ip->i_qadata->qa_qd_num = 0; |
601 | } | 634 | } |
602 | 635 | ||
603 | static int sort_qd(const void *a, const void *b) | 636 | static int sort_qd(const void *a, const void *b) |
@@ -843,7 +876,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda) | |||
843 | unsigned int nalloc = 0, blocks; | 876 | unsigned int nalloc = 0, blocks; |
844 | int error; | 877 | int error; |
845 | 878 | ||
846 | error = gfs2_rs_alloc(ip); | 879 | error = gfs2_rsqa_alloc(ip); |
847 | if (error) | 880 | if (error) |
848 | return error; | 881 | return error; |
849 | 882 | ||
@@ -1003,23 +1036,23 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
1003 | { | 1036 | { |
1004 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1037 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1005 | struct gfs2_quota_data *qd; | 1038 | struct gfs2_quota_data *qd; |
1006 | unsigned int x; | 1039 | u32 x; |
1007 | int error = 0; | 1040 | int error = 0; |
1008 | 1041 | ||
1009 | error = gfs2_quota_hold(ip, uid, gid); | ||
1010 | if (error) | ||
1011 | return error; | ||
1012 | |||
1013 | if (capable(CAP_SYS_RESOURCE) || | 1042 | if (capable(CAP_SYS_RESOURCE) || |
1014 | sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 1043 | sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
1015 | return 0; | 1044 | return 0; |
1016 | 1045 | ||
1017 | sort(ip->i_res->rs_qa_qd, ip->i_res->rs_qa_qd_num, | 1046 | error = gfs2_quota_hold(ip, uid, gid); |
1047 | if (error) | ||
1048 | return error; | ||
1049 | |||
1050 | sort(ip->i_qadata->qa_qd, ip->i_qadata->qa_qd_num, | ||
1018 | sizeof(struct gfs2_quota_data *), sort_qd, NULL); | 1051 | sizeof(struct gfs2_quota_data *), sort_qd, NULL); |
1019 | 1052 | ||
1020 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1053 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
1021 | qd = ip->i_res->rs_qa_qd[x]; | 1054 | qd = ip->i_qadata->qa_qd[x]; |
1022 | error = do_glock(qd, NO_FORCE, &ip->i_res->rs_qa_qd_ghs[x]); | 1055 | error = do_glock(qd, NO_FORCE, &ip->i_qadata->qa_qd_ghs[x]); |
1023 | if (error) | 1056 | if (error) |
1024 | break; | 1057 | break; |
1025 | } | 1058 | } |
@@ -1028,7 +1061,7 @@ int gfs2_quota_lock(struct gfs2_inode *ip, kuid_t uid, kgid_t gid) | |||
1028 | set_bit(GIF_QD_LOCKED, &ip->i_flags); | 1061 | set_bit(GIF_QD_LOCKED, &ip->i_flags); |
1029 | else { | 1062 | else { |
1030 | while (x--) | 1063 | while (x--) |
1031 | gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]); | 1064 | gfs2_glock_dq_uninit(&ip->i_qadata->qa_qd_ghs[x]); |
1032 | gfs2_quota_unhold(ip); | 1065 | gfs2_quota_unhold(ip); |
1033 | } | 1066 | } |
1034 | 1067 | ||
@@ -1076,20 +1109,20 @@ void gfs2_quota_unlock(struct gfs2_inode *ip) | |||
1076 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1109 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1077 | struct gfs2_quota_data *qda[4]; | 1110 | struct gfs2_quota_data *qda[4]; |
1078 | unsigned int count = 0; | 1111 | unsigned int count = 0; |
1079 | unsigned int x; | 1112 | u32 x; |
1080 | int found; | 1113 | int found; |
1081 | 1114 | ||
1082 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) | 1115 | if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) |
1083 | goto out; | 1116 | goto out; |
1084 | 1117 | ||
1085 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1118 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
1086 | struct gfs2_quota_data *qd; | 1119 | struct gfs2_quota_data *qd; |
1087 | int sync; | 1120 | int sync; |
1088 | 1121 | ||
1089 | qd = ip->i_res->rs_qa_qd[x]; | 1122 | qd = ip->i_qadata->qa_qd[x]; |
1090 | sync = need_sync(qd); | 1123 | sync = need_sync(qd); |
1091 | 1124 | ||
1092 | gfs2_glock_dq_uninit(&ip->i_res->rs_qa_qd_ghs[x]); | 1125 | gfs2_glock_dq_uninit(&ip->i_qadata->qa_qd_ghs[x]); |
1093 | if (!sync) | 1126 | if (!sync) |
1094 | continue; | 1127 | continue; |
1095 | 1128 | ||
@@ -1158,7 +1191,7 @@ int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid, | |||
1158 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1191 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1159 | struct gfs2_quota_data *qd; | 1192 | struct gfs2_quota_data *qd; |
1160 | s64 value, warn, limit; | 1193 | s64 value, warn, limit; |
1161 | unsigned int x; | 1194 | u32 x; |
1162 | int error = 0; | 1195 | int error = 0; |
1163 | 1196 | ||
1164 | ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */ | 1197 | ap->allowed = UINT_MAX; /* Assume we are permitted a whole lot */ |
@@ -1168,8 +1201,8 @@ int gfs2_quota_check(struct gfs2_inode *ip, kuid_t uid, kgid_t gid, | |||
1168 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) | 1201 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON) |
1169 | return 0; | 1202 | return 0; |
1170 | 1203 | ||
1171 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1204 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
1172 | qd = ip->i_res->rs_qa_qd[x]; | 1205 | qd = ip->i_qadata->qa_qd[x]; |
1173 | 1206 | ||
1174 | if (!(qid_eq(qd->qd_id, make_kqid_uid(uid)) || | 1207 | if (!(qid_eq(qd->qd_id, make_kqid_uid(uid)) || |
1175 | qid_eq(qd->qd_id, make_kqid_gid(gid)))) | 1208 | qid_eq(qd->qd_id, make_kqid_gid(gid)))) |
@@ -1216,15 +1249,17 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | |||
1216 | kuid_t uid, kgid_t gid) | 1249 | kuid_t uid, kgid_t gid) |
1217 | { | 1250 | { |
1218 | struct gfs2_quota_data *qd; | 1251 | struct gfs2_quota_data *qd; |
1219 | unsigned int x; | 1252 | u32 x; |
1253 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1220 | 1254 | ||
1221 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change)) | 1255 | if (sdp->sd_args.ar_quota != GFS2_QUOTA_ON || |
1256 | gfs2_assert_warn(sdp, change)) | ||
1222 | return; | 1257 | return; |
1223 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) | 1258 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) |
1224 | return; | 1259 | return; |
1225 | 1260 | ||
1226 | for (x = 0; x < ip->i_res->rs_qa_qd_num; x++) { | 1261 | for (x = 0; x < ip->i_qadata->qa_qd_num; x++) { |
1227 | qd = ip->i_res->rs_qa_qd[x]; | 1262 | qd = ip->i_qadata->qa_qd[x]; |
1228 | 1263 | ||
1229 | if (qid_eq(qd->qd_id, make_kqid_uid(uid)) || | 1264 | if (qid_eq(qd->qd_id, make_kqid_uid(uid)) || |
1230 | qid_eq(qd->qd_id, make_kqid_gid(gid))) { | 1265 | qid_eq(qd->qd_id, make_kqid_gid(gid))) { |
@@ -1635,7 +1670,7 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, | |||
1635 | if (error) | 1670 | if (error) |
1636 | return error; | 1671 | return error; |
1637 | 1672 | ||
1638 | error = gfs2_rs_alloc(ip); | 1673 | error = gfs2_rsqa_alloc(ip); |
1639 | if (error) | 1674 | if (error) |
1640 | goto out_put; | 1675 | goto out_put; |
1641 | 1676 | ||
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h index ad04b3acae2b..5e47c935a515 100644 --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h | |||
@@ -18,6 +18,8 @@ struct gfs2_sbd; | |||
18 | #define NO_UID_QUOTA_CHANGE INVALID_UID | 18 | #define NO_UID_QUOTA_CHANGE INVALID_UID |
19 | #define NO_GID_QUOTA_CHANGE INVALID_GID | 19 | #define NO_GID_QUOTA_CHANGE INVALID_GID |
20 | 20 | ||
21 | extern int gfs2_qa_alloc(struct gfs2_inode *ip); | ||
22 | extern void gfs2_qa_delete(struct gfs2_inode *ip, atomic_t *wcount); | ||
21 | extern int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); | 23 | extern int gfs2_quota_hold(struct gfs2_inode *ip, kuid_t uid, kgid_t gid); |
22 | extern void gfs2_quota_unhold(struct gfs2_inode *ip); | 24 | extern void gfs2_quota_unhold(struct gfs2_inode *ip); |
23 | 25 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index c134c0462cee..07c0265aa195 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -596,27 +596,13 @@ void gfs2_free_clones(struct gfs2_rgrpd *rgd) | |||
596 | } | 596 | } |
597 | 597 | ||
598 | /** | 598 | /** |
599 | * gfs2_rs_alloc - make sure we have a reservation assigned to the inode | 599 | * gfs2_rsqa_alloc - make sure we have a reservation assigned to the inode |
600 | * plus a quota allocations data structure, if necessary | ||
600 | * @ip: the inode for this reservation | 601 | * @ip: the inode for this reservation |
601 | */ | 602 | */ |
602 | int gfs2_rs_alloc(struct gfs2_inode *ip) | 603 | int gfs2_rsqa_alloc(struct gfs2_inode *ip) |
603 | { | 604 | { |
604 | int error = 0; | 605 | return gfs2_qa_alloc(ip); |
605 | |||
606 | down_write(&ip->i_rw_mutex); | ||
607 | if (ip->i_res) | ||
608 | goto out; | ||
609 | |||
610 | ip->i_res = kmem_cache_zalloc(gfs2_rsrv_cachep, GFP_NOFS); | ||
611 | if (!ip->i_res) { | ||
612 | error = -ENOMEM; | ||
613 | goto out; | ||
614 | } | ||
615 | |||
616 | RB_CLEAR_NODE(&ip->i_res->rs_node); | ||
617 | out: | ||
618 | up_write(&ip->i_rw_mutex); | ||
619 | return error; | ||
620 | } | 606 | } |
621 | 607 | ||
622 | static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) | 608 | static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) |
@@ -678,21 +664,20 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs) | |||
678 | } | 664 | } |
679 | 665 | ||
680 | /** | 666 | /** |
681 | * gfs2_rs_delete - delete a multi-block reservation | 667 | * gfs2_rsqa_delete - delete a multi-block reservation and quota allocation |
682 | * @ip: The inode for this reservation | 668 | * @ip: The inode for this reservation |
683 | * @wcount: The inode's write count, or NULL | 669 | * @wcount: The inode's write count, or NULL |
684 | * | 670 | * |
685 | */ | 671 | */ |
686 | void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount) | 672 | void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount) |
687 | { | 673 | { |
688 | down_write(&ip->i_rw_mutex); | 674 | down_write(&ip->i_rw_mutex); |
689 | if (ip->i_res && ((wcount == NULL) || (atomic_read(wcount) <= 1))) { | 675 | if ((wcount == NULL) || (atomic_read(wcount) <= 1)) { |
690 | gfs2_rs_deltree(ip->i_res); | 676 | gfs2_rs_deltree(&ip->i_res); |
691 | BUG_ON(ip->i_res->rs_free); | 677 | BUG_ON(ip->i_res.rs_free); |
692 | kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); | ||
693 | ip->i_res = NULL; | ||
694 | } | 678 | } |
695 | up_write(&ip->i_rw_mutex); | 679 | up_write(&ip->i_rw_mutex); |
680 | gfs2_qa_delete(ip, wcount); | ||
696 | } | 681 | } |
697 | 682 | ||
698 | /** | 683 | /** |
@@ -1158,7 +1143,7 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
1158 | 1143 | ||
1159 | for (x = 0; x < length; x++) { | 1144 | for (x = 0; x < length; x++) { |
1160 | bi = rgd->rd_bits + x; | 1145 | bi = rgd->rd_bits + x; |
1161 | error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); | 1146 | error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, 0, &bi->bi_bh); |
1162 | if (error) | 1147 | if (error) |
1163 | goto fail; | 1148 | goto fail; |
1164 | } | 1149 | } |
@@ -1456,7 +1441,7 @@ static void rs_insert(struct gfs2_inode *ip) | |||
1456 | { | 1441 | { |
1457 | struct rb_node **newn, *parent = NULL; | 1442 | struct rb_node **newn, *parent = NULL; |
1458 | int rc; | 1443 | int rc; |
1459 | struct gfs2_blkreserv *rs = ip->i_res; | 1444 | struct gfs2_blkreserv *rs = &ip->i_res; |
1460 | struct gfs2_rgrpd *rgd = rs->rs_rbm.rgd; | 1445 | struct gfs2_rgrpd *rgd = rs->rs_rbm.rgd; |
1461 | u64 fsblock = gfs2_rbm_to_block(&rs->rs_rbm); | 1446 | u64 fsblock = gfs2_rbm_to_block(&rs->rs_rbm); |
1462 | 1447 | ||
@@ -1503,7 +1488,7 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip, | |||
1503 | { | 1488 | { |
1504 | struct gfs2_rbm rbm = { .rgd = rgd, }; | 1489 | struct gfs2_rbm rbm = { .rgd = rgd, }; |
1505 | u64 goal; | 1490 | u64 goal; |
1506 | struct gfs2_blkreserv *rs = ip->i_res; | 1491 | struct gfs2_blkreserv *rs = &ip->i_res; |
1507 | u32 extlen; | 1492 | u32 extlen; |
1508 | u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved; | 1493 | u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved; |
1509 | int ret; | 1494 | int ret; |
@@ -1574,7 +1559,7 @@ static u64 gfs2_next_unreserved_block(struct gfs2_rgrpd *rgd, u64 block, | |||
1574 | } | 1559 | } |
1575 | 1560 | ||
1576 | if (n) { | 1561 | if (n) { |
1577 | while ((rs_cmp(block, length, rs) == 0) && (ip->i_res != rs)) { | 1562 | while ((rs_cmp(block, length, rs) == 0) && (&ip->i_res != rs)) { |
1578 | block = gfs2_rbm_to_block(&rs->rs_rbm) + rs->rs_free; | 1563 | block = gfs2_rbm_to_block(&rs->rs_rbm) + rs->rs_free; |
1579 | n = n->rb_right; | 1564 | n = n->rb_right; |
1580 | if (n == NULL) | 1565 | if (n == NULL) |
@@ -1804,7 +1789,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip | |||
1804 | continue; | 1789 | continue; |
1805 | *last_unlinked = block; | 1790 | *last_unlinked = block; |
1806 | 1791 | ||
1807 | error = gfs2_glock_get(sdp, block, &gfs2_inode_glops, CREATE, &gl); | 1792 | error = gfs2_glock_get(sdp, block, &gfs2_iopen_glops, CREATE, &gl); |
1808 | if (error) | 1793 | if (error) |
1809 | continue; | 1794 | continue; |
1810 | 1795 | ||
@@ -1984,7 +1969,7 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap) | |||
1984 | { | 1969 | { |
1985 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1970 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1986 | struct gfs2_rgrpd *begin = NULL; | 1971 | struct gfs2_rgrpd *begin = NULL; |
1987 | struct gfs2_blkreserv *rs = ip->i_res; | 1972 | struct gfs2_blkreserv *rs = &ip->i_res; |
1988 | int error = 0, rg_locked, flags = 0; | 1973 | int error = 0, rg_locked, flags = 0; |
1989 | u64 last_unlinked = NO_BLOCK; | 1974 | u64 last_unlinked = NO_BLOCK; |
1990 | int loops = 0; | 1975 | int loops = 0; |
@@ -2113,7 +2098,7 @@ next_rgrp: | |||
2113 | 2098 | ||
2114 | void gfs2_inplace_release(struct gfs2_inode *ip) | 2099 | void gfs2_inplace_release(struct gfs2_inode *ip) |
2115 | { | 2100 | { |
2116 | struct gfs2_blkreserv *rs = ip->i_res; | 2101 | struct gfs2_blkreserv *rs = &ip->i_res; |
2117 | 2102 | ||
2118 | if (rs->rs_rgd_gh.gh_gl) | 2103 | if (rs->rs_rgd_gh.gh_gl) |
2119 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); | 2104 | gfs2_glock_dq_uninit(&rs->rs_rgd_gh); |
@@ -2267,7 +2252,7 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd) | |||
2267 | static void gfs2_adjust_reservation(struct gfs2_inode *ip, | 2252 | static void gfs2_adjust_reservation(struct gfs2_inode *ip, |
2268 | const struct gfs2_rbm *rbm, unsigned len) | 2253 | const struct gfs2_rbm *rbm, unsigned len) |
2269 | { | 2254 | { |
2270 | struct gfs2_blkreserv *rs = ip->i_res; | 2255 | struct gfs2_blkreserv *rs = &ip->i_res; |
2271 | struct gfs2_rgrpd *rgd = rbm->rgd; | 2256 | struct gfs2_rgrpd *rgd = rbm->rgd; |
2272 | unsigned rlen; | 2257 | unsigned rlen; |
2273 | u64 block; | 2258 | u64 block; |
@@ -2310,8 +2295,8 @@ static void gfs2_set_alloc_start(struct gfs2_rbm *rbm, | |||
2310 | { | 2295 | { |
2311 | u64 goal; | 2296 | u64 goal; |
2312 | 2297 | ||
2313 | if (gfs2_rs_active(ip->i_res)) { | 2298 | if (gfs2_rs_active(&ip->i_res)) { |
2314 | *rbm = ip->i_res->rs_rbm; | 2299 | *rbm = ip->i_res.rs_rbm; |
2315 | return; | 2300 | return; |
2316 | } | 2301 | } |
2317 | 2302 | ||
@@ -2365,7 +2350,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
2365 | gfs2_alloc_extent(&rbm, dinode, nblocks); | 2350 | gfs2_alloc_extent(&rbm, dinode, nblocks); |
2366 | block = gfs2_rbm_to_block(&rbm); | 2351 | block = gfs2_rbm_to_block(&rbm); |
2367 | rbm.rgd->rd_last_alloc = block - rbm.rgd->rd_data0; | 2352 | rbm.rgd->rd_last_alloc = block - rbm.rgd->rd_data0; |
2368 | if (gfs2_rs_active(ip->i_res)) | 2353 | if (gfs2_rs_active(&ip->i_res)) |
2369 | gfs2_adjust_reservation(ip, &rbm, *nblocks); | 2354 | gfs2_adjust_reservation(ip, &rbm, *nblocks); |
2370 | ndata = *nblocks; | 2355 | ndata = *nblocks; |
2371 | if (dinode) | 2356 | if (dinode) |
diff --git a/fs/gfs2/rgrp.h b/fs/gfs2/rgrp.h index c0ab33fa3eed..66b51cf66dfa 100644 --- a/fs/gfs2/rgrp.h +++ b/fs/gfs2/rgrp.h | |||
@@ -49,9 +49,9 @@ extern void gfs2_inplace_release(struct gfs2_inode *ip); | |||
49 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, | 49 | extern int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *n, |
50 | bool dinode, u64 *generation); | 50 | bool dinode, u64 *generation); |
51 | 51 | ||
52 | extern int gfs2_rs_alloc(struct gfs2_inode *ip); | 52 | extern int gfs2_rsqa_alloc(struct gfs2_inode *ip); |
53 | extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); | 53 | extern void gfs2_rs_deltree(struct gfs2_blkreserv *rs); |
54 | extern void gfs2_rs_delete(struct gfs2_inode *ip, atomic_t *wcount); | 54 | extern void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount); |
55 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); | 55 | extern void __gfs2_free_blocks(struct gfs2_inode *ip, u64 bstart, u32 blen, int meta); |
56 | 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); |
57 | 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); |
@@ -78,7 +78,7 @@ extern int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, | |||
78 | extern int gfs2_fitrim(struct file *filp, void __user *argp); | 78 | extern int gfs2_fitrim(struct file *filp, void __user *argp); |
79 | 79 | ||
80 | /* This is how to tell if a reservation is in the rgrp tree: */ | 80 | /* This is how to tell if a reservation is in the rgrp tree: */ |
81 | static inline bool gfs2_rs_active(struct gfs2_blkreserv *rs) | 81 | static inline bool gfs2_rs_active(const struct gfs2_blkreserv *rs) |
82 | { | 82 | { |
83 | return rs && !RB_EMPTY_NODE(&rs->rs_node); | 83 | return rs && !RB_EMPTY_NODE(&rs->rs_node); |
84 | } | 84 | } |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 894fb01a91da..8f960a51a9a0 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -83,6 +83,8 @@ enum { | |||
83 | Opt_nobarrier, | 83 | Opt_nobarrier, |
84 | Opt_rgrplvb, | 84 | Opt_rgrplvb, |
85 | Opt_norgrplvb, | 85 | Opt_norgrplvb, |
86 | Opt_loccookie, | ||
87 | Opt_noloccookie, | ||
86 | Opt_error, | 88 | Opt_error, |
87 | }; | 89 | }; |
88 | 90 | ||
@@ -122,6 +124,8 @@ static const match_table_t tokens = { | |||
122 | {Opt_nobarrier, "nobarrier"}, | 124 | {Opt_nobarrier, "nobarrier"}, |
123 | {Opt_rgrplvb, "rgrplvb"}, | 125 | {Opt_rgrplvb, "rgrplvb"}, |
124 | {Opt_norgrplvb, "norgrplvb"}, | 126 | {Opt_norgrplvb, "norgrplvb"}, |
127 | {Opt_loccookie, "loccookie"}, | ||
128 | {Opt_noloccookie, "noloccookie"}, | ||
125 | {Opt_error, NULL} | 129 | {Opt_error, NULL} |
126 | }; | 130 | }; |
127 | 131 | ||
@@ -278,6 +282,12 @@ int gfs2_mount_args(struct gfs2_args *args, char *options) | |||
278 | case Opt_norgrplvb: | 282 | case Opt_norgrplvb: |
279 | args->ar_rgrplvb = 0; | 283 | args->ar_rgrplvb = 0; |
280 | break; | 284 | break; |
285 | case Opt_loccookie: | ||
286 | args->ar_loccookie = 1; | ||
287 | break; | ||
288 | case Opt_noloccookie: | ||
289 | args->ar_loccookie = 0; | ||
290 | break; | ||
281 | case Opt_error: | 291 | case Opt_error: |
282 | default: | 292 | default: |
283 | pr_warn("invalid mount option: %s\n", o); | 293 | pr_warn("invalid mount option: %s\n", o); |
@@ -556,6 +566,7 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, | |||
556 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | 566 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
557 | 567 | ||
558 | gfs2_trans_add_meta(l_ip->i_gl, l_bh); | 568 | gfs2_trans_add_meta(l_ip->i_gl, l_bh); |
569 | gfs2_trans_add_meta(m_ip->i_gl, m_bh); | ||
559 | 570 | ||
560 | spin_lock(&sdp->sd_statfs_spin); | 571 | spin_lock(&sdp->sd_statfs_spin); |
561 | m_sc->sc_total += l_sc->sc_total; | 572 | m_sc->sc_total += l_sc->sc_total; |
@@ -564,10 +575,8 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, | |||
564 | memset(l_sc, 0, sizeof(struct gfs2_statfs_change)); | 575 | memset(l_sc, 0, sizeof(struct gfs2_statfs_change)); |
565 | memset(l_bh->b_data + sizeof(struct gfs2_dinode), | 576 | memset(l_bh->b_data + sizeof(struct gfs2_dinode), |
566 | 0, sizeof(struct gfs2_statfs_change)); | 577 | 0, sizeof(struct gfs2_statfs_change)); |
567 | spin_unlock(&sdp->sd_statfs_spin); | ||
568 | |||
569 | gfs2_trans_add_meta(m_ip->i_gl, m_bh); | ||
570 | gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); | 578 | gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); |
579 | spin_unlock(&sdp->sd_statfs_spin); | ||
571 | } | 580 | } |
572 | 581 | ||
573 | int gfs2_statfs_sync(struct super_block *sb, int type) | 582 | int gfs2_statfs_sync(struct super_block *sb, int type) |
@@ -842,10 +851,6 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
842 | gfs2_quota_sync(sdp->sd_vfs, 0); | 851 | gfs2_quota_sync(sdp->sd_vfs, 0); |
843 | gfs2_statfs_sync(sdp->sd_vfs, 0); | 852 | gfs2_statfs_sync(sdp->sd_vfs, 0); |
844 | 853 | ||
845 | down_write(&sdp->sd_log_flush_lock); | ||
846 | clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); | ||
847 | up_write(&sdp->sd_log_flush_lock); | ||
848 | |||
849 | gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH); | 854 | gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH); |
850 | wait_event(sdp->sd_reserving_log_wait, atomic_read(&sdp->sd_reserving_log) == 0); | 855 | wait_event(sdp->sd_reserving_log_wait, atomic_read(&sdp->sd_reserving_log) == 0); |
851 | gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); | 856 | gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); |
@@ -1419,6 +1424,8 @@ static int gfs2_show_options(struct seq_file *s, struct dentry *root) | |||
1419 | seq_puts(s, ",demote_interface_used"); | 1424 | seq_puts(s, ",demote_interface_used"); |
1420 | if (args->ar_rgrplvb) | 1425 | if (args->ar_rgrplvb) |
1421 | seq_puts(s, ",rgrplvb"); | 1426 | seq_puts(s, ",rgrplvb"); |
1427 | if (args->ar_loccookie) | ||
1428 | seq_puts(s, ",loccookie"); | ||
1422 | return 0; | 1429 | return 0; |
1423 | } | 1430 | } |
1424 | 1431 | ||
@@ -1512,6 +1519,7 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1512 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1519 | struct gfs2_sbd *sdp = sb->s_fs_info; |
1513 | struct gfs2_inode *ip = GFS2_I(inode); | 1520 | struct gfs2_inode *ip = GFS2_I(inode); |
1514 | struct gfs2_holder gh; | 1521 | struct gfs2_holder gh; |
1522 | struct address_space *metamapping; | ||
1515 | int error; | 1523 | int error; |
1516 | 1524 | ||
1517 | if (test_bit(GIF_FREE_VFS_INODE, &ip->i_flags)) { | 1525 | if (test_bit(GIF_FREE_VFS_INODE, &ip->i_flags)) { |
@@ -1526,7 +1534,8 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1526 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh); | 1534 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh); |
1527 | if (unlikely(error)) { | 1535 | if (unlikely(error)) { |
1528 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; | 1536 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; |
1529 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 1537 | gfs2_glock_dq_wait(&ip->i_iopen_gh); |
1538 | gfs2_holder_uninit(&ip->i_iopen_gh); | ||
1530 | goto out; | 1539 | goto out; |
1531 | } | 1540 | } |
1532 | 1541 | ||
@@ -1575,8 +1584,8 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1575 | 1584 | ||
1576 | out_truncate: | 1585 | out_truncate: |
1577 | gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); | 1586 | gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); |
1587 | metamapping = gfs2_glock2aspace(ip->i_gl); | ||
1578 | if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) { | 1588 | if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) { |
1579 | struct address_space *metamapping = gfs2_glock2aspace(ip->i_gl); | ||
1580 | filemap_fdatawrite(metamapping); | 1589 | filemap_fdatawrite(metamapping); |
1581 | filemap_fdatawait(metamapping); | 1590 | filemap_fdatawait(metamapping); |
1582 | } | 1591 | } |
@@ -1589,16 +1598,17 @@ out_truncate: | |||
1589 | goto out_unlock; | 1598 | goto out_unlock; |
1590 | /* Needs to be done before glock release & also in a transaction */ | 1599 | /* Needs to be done before glock release & also in a transaction */ |
1591 | truncate_inode_pages(&inode->i_data, 0); | 1600 | truncate_inode_pages(&inode->i_data, 0); |
1601 | truncate_inode_pages(metamapping, 0); | ||
1592 | gfs2_trans_end(sdp); | 1602 | gfs2_trans_end(sdp); |
1593 | 1603 | ||
1594 | out_unlock: | 1604 | out_unlock: |
1595 | /* Error path for case 1 */ | 1605 | /* Error path for case 1 */ |
1596 | if (gfs2_rs_active(ip->i_res)) | 1606 | if (gfs2_rs_active(&ip->i_res)) |
1597 | gfs2_rs_deltree(ip->i_res); | 1607 | gfs2_rs_deltree(&ip->i_res); |
1598 | 1608 | ||
1599 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { | 1609 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { |
1600 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; | 1610 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; |
1601 | gfs2_glock_dq(&ip->i_iopen_gh); | 1611 | gfs2_glock_dq_wait(&ip->i_iopen_gh); |
1602 | } | 1612 | } |
1603 | gfs2_holder_uninit(&ip->i_iopen_gh); | 1613 | gfs2_holder_uninit(&ip->i_iopen_gh); |
1604 | gfs2_glock_dq_uninit(&gh); | 1614 | gfs2_glock_dq_uninit(&gh); |
@@ -1607,7 +1617,7 @@ out_unlock: | |||
1607 | out: | 1617 | out: |
1608 | /* Case 3 starts here */ | 1618 | /* Case 3 starts here */ |
1609 | truncate_inode_pages_final(&inode->i_data); | 1619 | truncate_inode_pages_final(&inode->i_data); |
1610 | gfs2_rs_delete(ip, NULL); | 1620 | gfs2_rsqa_delete(ip, NULL); |
1611 | gfs2_ordered_del_inode(ip); | 1621 | gfs2_ordered_del_inode(ip); |
1612 | clear_inode(inode); | 1622 | clear_inode(inode); |
1613 | gfs2_dir_hash_inval(ip); | 1623 | gfs2_dir_hash_inval(ip); |
@@ -1619,7 +1629,8 @@ out: | |||
1619 | if (ip->i_iopen_gh.gh_gl) { | 1629 | if (ip->i_iopen_gh.gh_gl) { |
1620 | ip->i_iopen_gh.gh_gl->gl_object = NULL; | 1630 | ip->i_iopen_gh.gh_gl->gl_object = NULL; |
1621 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; | 1631 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; |
1622 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 1632 | gfs2_glock_dq_wait(&ip->i_iopen_gh); |
1633 | gfs2_holder_uninit(&ip->i_iopen_gh); | ||
1623 | } | 1634 | } |
1624 | } | 1635 | } |
1625 | 1636 | ||
@@ -1632,7 +1643,9 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb) | |||
1632 | ip->i_flags = 0; | 1643 | ip->i_flags = 0; |
1633 | ip->i_gl = NULL; | 1644 | ip->i_gl = NULL; |
1634 | ip->i_rgd = NULL; | 1645 | ip->i_rgd = NULL; |
1635 | ip->i_res = NULL; | 1646 | memset(&ip->i_res, 0, sizeof(ip->i_res)); |
1647 | RB_CLEAR_NODE(&ip->i_res.rs_node); | ||
1648 | ip->i_rahead = 0; | ||
1636 | } | 1649 | } |
1637 | return &ip->i_inode; | 1650 | return &ip->i_inode; |
1638 | } | 1651 | } |
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 86d2035ac669..cf645835710f 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c | |||
@@ -27,7 +27,7 @@ struct kmem_cache *gfs2_inode_cachep __read_mostly; | |||
27 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; | 27 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; |
28 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; | 28 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; |
29 | struct kmem_cache *gfs2_quotad_cachep __read_mostly; | 29 | struct kmem_cache *gfs2_quotad_cachep __read_mostly; |
30 | struct kmem_cache *gfs2_rsrv_cachep __read_mostly; | 30 | struct kmem_cache *gfs2_qadata_cachep __read_mostly; |
31 | mempool_t *gfs2_page_pool __read_mostly; | 31 | mempool_t *gfs2_page_pool __read_mostly; |
32 | 32 | ||
33 | void gfs2_assert_i(struct gfs2_sbd *sdp) | 33 | void gfs2_assert_i(struct gfs2_sbd *sdp) |
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index cbdcbdf39614..c81295f407f6 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h | |||
@@ -149,7 +149,7 @@ extern struct kmem_cache *gfs2_inode_cachep; | |||
149 | extern struct kmem_cache *gfs2_bufdata_cachep; | 149 | extern struct kmem_cache *gfs2_bufdata_cachep; |
150 | extern struct kmem_cache *gfs2_rgrpd_cachep; | 150 | extern struct kmem_cache *gfs2_rgrpd_cachep; |
151 | extern struct kmem_cache *gfs2_quotad_cachep; | 151 | extern struct kmem_cache *gfs2_quotad_cachep; |
152 | extern struct kmem_cache *gfs2_rsrv_cachep; | 152 | extern struct kmem_cache *gfs2_qadata_cachep; |
153 | extern mempool_t *gfs2_page_pool; | 153 | extern mempool_t *gfs2_page_pool; |
154 | 154 | ||
155 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, | 155 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, |
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 84f2d81fe451..e8dfb4740c04 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
@@ -119,7 +119,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | |||
119 | __be64 *eablk, *end; | 119 | __be64 *eablk, *end; |
120 | int error; | 120 | int error; |
121 | 121 | ||
122 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &bh); | 122 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, &bh); |
123 | if (error) | 123 | if (error) |
124 | return error; | 124 | return error; |
125 | 125 | ||
@@ -143,7 +143,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | |||
143 | break; | 143 | break; |
144 | bn = be64_to_cpu(*eablk); | 144 | bn = be64_to_cpu(*eablk); |
145 | 145 | ||
146 | error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, &eabh); | 146 | error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, 0, &eabh); |
147 | if (error) | 147 | if (error) |
148 | break; | 148 | break; |
149 | error = ea_foreach_i(ip, eabh, ea_call, data); | 149 | error = ea_foreach_i(ip, eabh, ea_call, data); |
@@ -477,7 +477,7 @@ static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
477 | return -ENOMEM; | 477 | return -ENOMEM; |
478 | 478 | ||
479 | for (x = 0; x < nptrs; x++) { | 479 | for (x = 0; x < nptrs; x++) { |
480 | error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0, | 480 | error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0, 0, |
481 | bh + x); | 481 | bh + x); |
482 | if (error) { | 482 | if (error) { |
483 | while (x--) | 483 | while (x--) |
@@ -979,7 +979,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
979 | if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) { | 979 | if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) { |
980 | __be64 *end; | 980 | __be64 *end; |
981 | 981 | ||
982 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, | 982 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, |
983 | &indbh); | 983 | &indbh); |
984 | if (error) | 984 | if (error) |
985 | return error; | 985 | return error; |
@@ -1256,7 +1256,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1256 | 1256 | ||
1257 | memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); | 1257 | memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); |
1258 | 1258 | ||
1259 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh); | 1259 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, &indbh); |
1260 | if (error) | 1260 | if (error) |
1261 | return error; | 1261 | return error; |
1262 | 1262 | ||
diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 1a763eaae0bb..7c4be7711c81 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h | |||
@@ -297,6 +297,8 @@ struct gfs2_dinode { | |||
297 | 297 | ||
298 | #define GFS2_FNAMESIZE 255 | 298 | #define GFS2_FNAMESIZE 255 |
299 | #define GFS2_DIRENT_SIZE(name_len) ((sizeof(struct gfs2_dirent) + (name_len) + 7) & ~7) | 299 | #define GFS2_DIRENT_SIZE(name_len) ((sizeof(struct gfs2_dirent) + (name_len) + 7) & ~7) |
300 | #define GFS2_MIN_DIRENT_SIZE (GFS2_DIRENT_SIZE(1)) | ||
301 | |||
300 | 302 | ||
301 | struct gfs2_dirent { | 303 | struct gfs2_dirent { |
302 | struct gfs2_inum de_inum; | 304 | struct gfs2_inum de_inum; |
@@ -304,11 +306,12 @@ struct gfs2_dirent { | |||
304 | __be16 de_rec_len; | 306 | __be16 de_rec_len; |
305 | __be16 de_name_len; | 307 | __be16 de_name_len; |
306 | __be16 de_type; | 308 | __be16 de_type; |
309 | __be16 de_rahead; | ||
307 | union { | 310 | union { |
308 | __u8 __pad[14]; | 311 | __u8 __pad[12]; |
309 | struct { | 312 | struct { |
310 | __be16 de_rahead; | 313 | __u32 de_cookie; /* ondisk value not used */ |
311 | __u8 pad2[12]; | 314 | __u8 pad3[8]; |
312 | }; | 315 | }; |
313 | }; | 316 | }; |
314 | }; | 317 | }; |