diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-05 21:52:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-05 21:52:54 -0500 |
commit | c54febae996d36c630f09209cd9983ecfda3fcad (patch) | |
tree | 35b2717dcd4e4ff2206cd468b5895afb16f49c8c /fs | |
parent | e42e4ba07bc72c0eb7c7ab3bf9e5076db90d0f37 (diff) | |
parent | eb8374e71f941a1b3c2ed6ea19dc809e7124dc5d (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw: (27 commits)
GFS2: Use DEFINE_SPINLOCK
GFS2: Fix use-after-free bug on umount (try #2)
Revert "GFS2: Fix use-after-free bug on umount"
GFS2: Streamline alloc calculations for writes
GFS2: Send useful information with uevent messages
GFS2: Fix use-after-free bug on umount
GFS2: Remove ancient, unused code
GFS2: Move four functions from super.c
GFS2: Fix bug in gfs2_lock_fs_check_clean()
GFS2: Send some sensible sysfs stuff
GFS2: Kill two daemons with one patch
GFS2: Move gfs2_recoverd into recovery.c
GFS2: Fix "truncate in progress" hang
GFS2: Clean up & move gfs2_quotad
GFS2: Add more detail to debugfs glock dumps
GFS2: Banish struct gfs2_rgrpd_host
GFS2: Move rg_free from gfs2_rgrpd_host to gfs2_rgrpd
GFS2: Move rg_igeneration into struct gfs2_rgrpd
GFS2: Banish struct gfs2_dinode_host
GFS2: Move i_size from gfs2_dinode_host and rename it to i_disksize
...
Diffstat (limited to 'fs')
42 files changed, 961 insertions, 1084 deletions
diff --git a/fs/gfs2/Makefile b/fs/gfs2/Makefile index ec65851ec80a..c1b4ec6a9650 100644 --- a/fs/gfs2/Makefile +++ b/fs/gfs2/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | obj-$(CONFIG_GFS2_FS) += gfs2.o | 1 | obj-$(CONFIG_GFS2_FS) += gfs2.o |
2 | gfs2-y := acl.o bmap.o daemon.o dir.o eaops.o eattr.o glock.o \ | 2 | gfs2-y := acl.o bmap.o dir.o eaops.o eattr.o glock.o \ |
3 | glops.o inode.o log.o lops.o locking.o main.o meta_io.o \ | 3 | glops.o inode.o log.o lops.o locking.o main.o meta_io.o \ |
4 | mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ | 4 | mount.o ops_address.o ops_dentry.o ops_export.o ops_file.o \ |
5 | ops_fstype.o ops_inode.o ops_super.o quota.o \ | 5 | ops_fstype.o ops_inode.o ops_super.o quota.o \ |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 3e9bd46f27e3..e335dceb6a4f 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -91,7 +91,7 @@ static int acl_get(struct gfs2_inode *ip, int access, struct posix_acl **acl, | |||
91 | struct gfs2_ea_location el_this; | 91 | struct gfs2_ea_location el_this; |
92 | int error; | 92 | int error; |
93 | 93 | ||
94 | if (!ip->i_di.di_eattr) | 94 | if (!ip->i_eattr) |
95 | return 0; | 95 | return 0; |
96 | 96 | ||
97 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 97 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index bec76b1c2bb0..11ffc56f1f81 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -75,9 +75,9 @@ static int gfs2_unstuffer_page(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
75 | void *kaddr = kmap(page); | 75 | void *kaddr = kmap(page); |
76 | 76 | ||
77 | memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), | 77 | memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), |
78 | ip->i_di.di_size); | 78 | ip->i_disksize); |
79 | memset(kaddr + ip->i_di.di_size, 0, | 79 | memset(kaddr + ip->i_disksize, 0, |
80 | PAGE_CACHE_SIZE - ip->i_di.di_size); | 80 | PAGE_CACHE_SIZE - ip->i_disksize); |
81 | kunmap(page); | 81 | kunmap(page); |
82 | 82 | ||
83 | SetPageUptodate(page); | 83 | SetPageUptodate(page); |
@@ -132,7 +132,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page) | |||
132 | if (error) | 132 | if (error) |
133 | goto out; | 133 | goto out; |
134 | 134 | ||
135 | if (ip->i_di.di_size) { | 135 | if (ip->i_disksize) { |
136 | /* Get a free block, fill it with the stuffed data, | 136 | /* Get a free block, fill it with the stuffed data, |
137 | and write it out to disk */ | 137 | and write it out to disk */ |
138 | 138 | ||
@@ -159,7 +159,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page) | |||
159 | di = (struct gfs2_dinode *)dibh->b_data; | 159 | di = (struct gfs2_dinode *)dibh->b_data; |
160 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 160 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
161 | 161 | ||
162 | if (ip->i_di.di_size) { | 162 | if (ip->i_disksize) { |
163 | *(__be64 *)(di + 1) = cpu_to_be64(block); | 163 | *(__be64 *)(di + 1) = cpu_to_be64(block); |
164 | gfs2_add_inode_blocks(&ip->i_inode, 1); | 164 | gfs2_add_inode_blocks(&ip->i_inode, 1); |
165 | di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); | 165 | di->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); |
@@ -926,7 +926,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
926 | } | 926 | } |
927 | } | 927 | } |
928 | 928 | ||
929 | ip->i_di.di_size = size; | 929 | ip->i_disksize = size; |
930 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 930 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
931 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 931 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
932 | gfs2_dinode_out(ip, dibh->b_data); | 932 | gfs2_dinode_out(ip, dibh->b_data); |
@@ -1033,7 +1033,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
1033 | goto out; | 1033 | goto out; |
1034 | 1034 | ||
1035 | if (gfs2_is_stuffed(ip)) { | 1035 | if (gfs2_is_stuffed(ip)) { |
1036 | ip->i_di.di_size = size; | 1036 | ip->i_disksize = size; |
1037 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 1037 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1038 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1038 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1039 | gfs2_dinode_out(ip, dibh->b_data); | 1039 | gfs2_dinode_out(ip, dibh->b_data); |
@@ -1045,9 +1045,9 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
1045 | error = gfs2_block_truncate_page(ip->i_inode.i_mapping); | 1045 | error = gfs2_block_truncate_page(ip->i_inode.i_mapping); |
1046 | 1046 | ||
1047 | if (!error) { | 1047 | if (!error) { |
1048 | ip->i_di.di_size = size; | 1048 | ip->i_disksize = size; |
1049 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 1049 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1050 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; | 1050 | ip->i_diskflags |= GFS2_DIF_TRUNC_IN_PROG; |
1051 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1051 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1052 | gfs2_dinode_out(ip, dibh->b_data); | 1052 | gfs2_dinode_out(ip, dibh->b_data); |
1053 | } | 1053 | } |
@@ -1114,13 +1114,13 @@ static int trunc_end(struct gfs2_inode *ip) | |||
1114 | if (error) | 1114 | if (error) |
1115 | goto out; | 1115 | goto out; |
1116 | 1116 | ||
1117 | if (!ip->i_di.di_size) { | 1117 | if (!ip->i_disksize) { |
1118 | ip->i_height = 0; | 1118 | ip->i_height = 0; |
1119 | ip->i_goal = ip->i_no_addr; | 1119 | ip->i_goal = ip->i_no_addr; |
1120 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 1120 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
1121 | } | 1121 | } |
1122 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 1122 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1123 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; | 1123 | ip->i_diskflags &= ~GFS2_DIF_TRUNC_IN_PROG; |
1124 | 1124 | ||
1125 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1125 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1126 | gfs2_dinode_out(ip, dibh->b_data); | 1126 | gfs2_dinode_out(ip, dibh->b_data); |
@@ -1205,9 +1205,9 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size) | |||
1205 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode))) | 1205 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode))) |
1206 | return -EINVAL; | 1206 | return -EINVAL; |
1207 | 1207 | ||
1208 | if (size > ip->i_di.di_size) | 1208 | if (size > ip->i_disksize) |
1209 | error = do_grow(ip, size); | 1209 | error = do_grow(ip, size); |
1210 | else if (size < ip->i_di.di_size) | 1210 | else if (size < ip->i_disksize) |
1211 | error = do_shrink(ip, size); | 1211 | error = do_shrink(ip, size); |
1212 | else | 1212 | else |
1213 | /* update time stamps */ | 1213 | /* update time stamps */ |
@@ -1219,7 +1219,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size) | |||
1219 | int gfs2_truncatei_resume(struct gfs2_inode *ip) | 1219 | int gfs2_truncatei_resume(struct gfs2_inode *ip) |
1220 | { | 1220 | { |
1221 | int error; | 1221 | int error; |
1222 | error = trunc_dealloc(ip, ip->i_di.di_size); | 1222 | error = trunc_dealloc(ip, ip->i_disksize); |
1223 | if (!error) | 1223 | if (!error) |
1224 | error = trunc_end(ip); | 1224 | error = trunc_end(ip); |
1225 | return error; | 1225 | return error; |
@@ -1231,35 +1231,6 @@ int gfs2_file_dealloc(struct gfs2_inode *ip) | |||
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | /** | 1233 | /** |
1234 | * gfs2_write_calc_reserv - calculate number of blocks needed to write to a file | ||
1235 | * @ip: the file | ||
1236 | * @len: the number of bytes to be written to the file | ||
1237 | * @data_blocks: returns the number of data blocks required | ||
1238 | * @ind_blocks: returns the number of indirect blocks required | ||
1239 | * | ||
1240 | */ | ||
1241 | |||
1242 | void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len, | ||
1243 | unsigned int *data_blocks, unsigned int *ind_blocks) | ||
1244 | { | ||
1245 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
1246 | unsigned int tmp; | ||
1247 | |||
1248 | if (gfs2_is_dir(ip)) { | ||
1249 | *data_blocks = DIV_ROUND_UP(len, sdp->sd_jbsize) + 2; | ||
1250 | *ind_blocks = 3 * (sdp->sd_max_jheight - 1); | ||
1251 | } else { | ||
1252 | *data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3; | ||
1253 | *ind_blocks = 3 * (sdp->sd_max_height - 1); | ||
1254 | } | ||
1255 | |||
1256 | for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) { | ||
1257 | tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs); | ||
1258 | *ind_blocks += tmp; | ||
1259 | } | ||
1260 | } | ||
1261 | |||
1262 | /** | ||
1263 | * gfs2_write_alloc_required - figure out if a write will require an allocation | 1234 | * gfs2_write_alloc_required - figure out if a write will require an allocation |
1264 | * @ip: the file being written to | 1235 | * @ip: the file being written to |
1265 | * @offset: the offset to write to | 1236 | * @offset: the offset to write to |
@@ -1276,6 +1247,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, | |||
1276 | struct buffer_head bh; | 1247 | struct buffer_head bh; |
1277 | unsigned int shift; | 1248 | unsigned int shift; |
1278 | u64 lblock, lblock_stop, size; | 1249 | u64 lblock, lblock_stop, size; |
1250 | u64 end_of_file; | ||
1279 | 1251 | ||
1280 | *alloc_required = 0; | 1252 | *alloc_required = 0; |
1281 | 1253 | ||
@@ -1291,19 +1263,12 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, | |||
1291 | 1263 | ||
1292 | *alloc_required = 1; | 1264 | *alloc_required = 1; |
1293 | shift = sdp->sd_sb.sb_bsize_shift; | 1265 | shift = sdp->sd_sb.sb_bsize_shift; |
1294 | if (gfs2_is_dir(ip)) { | 1266 | BUG_ON(gfs2_is_dir(ip)); |
1295 | unsigned int bsize = sdp->sd_jbsize; | 1267 | end_of_file = (ip->i_disksize + sdp->sd_sb.sb_bsize - 1) >> shift; |
1296 | lblock = offset; | 1268 | lblock = offset >> shift; |
1297 | do_div(lblock, bsize); | 1269 | lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; |
1298 | lblock_stop = offset + len + bsize - 1; | 1270 | if (lblock_stop > end_of_file) |
1299 | do_div(lblock_stop, bsize); | 1271 | return 0; |
1300 | } else { | ||
1301 | u64 end_of_file = (ip->i_di.di_size + sdp->sd_sb.sb_bsize - 1) >> shift; | ||
1302 | lblock = offset >> shift; | ||
1303 | lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; | ||
1304 | if (lblock_stop > end_of_file) | ||
1305 | return 0; | ||
1306 | } | ||
1307 | 1272 | ||
1308 | size = (lblock_stop - lblock) << shift; | 1273 | size = (lblock_stop - lblock) << shift; |
1309 | do { | 1274 | do { |
diff --git a/fs/gfs2/bmap.h b/fs/gfs2/bmap.h index 4e6cde2943bd..c983177e05ac 100644 --- a/fs/gfs2/bmap.h +++ b/fs/gfs2/bmap.h | |||
@@ -10,10 +10,40 @@ | |||
10 | #ifndef __BMAP_DOT_H__ | 10 | #ifndef __BMAP_DOT_H__ |
11 | #define __BMAP_DOT_H__ | 11 | #define __BMAP_DOT_H__ |
12 | 12 | ||
13 | #include "inode.h" | ||
14 | |||
13 | struct inode; | 15 | struct inode; |
14 | struct gfs2_inode; | 16 | struct gfs2_inode; |
15 | struct page; | 17 | struct page; |
16 | 18 | ||
19 | |||
20 | /** | ||
21 | * gfs2_write_calc_reserv - calculate number of blocks needed to write to a file | ||
22 | * @ip: the file | ||
23 | * @len: the number of bytes to be written to the file | ||
24 | * @data_blocks: returns the number of data blocks required | ||
25 | * @ind_blocks: returns the number of indirect blocks required | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | static inline void gfs2_write_calc_reserv(const struct gfs2_inode *ip, | ||
30 | unsigned int len, | ||
31 | unsigned int *data_blocks, | ||
32 | unsigned int *ind_blocks) | ||
33 | { | ||
34 | const struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
35 | unsigned int tmp; | ||
36 | |||
37 | BUG_ON(gfs2_is_dir(ip)); | ||
38 | *data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3; | ||
39 | *ind_blocks = 3 * (sdp->sd_max_height - 1); | ||
40 | |||
41 | for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) { | ||
42 | tmp = DIV_ROUND_UP(tmp, sdp->sd_inptrs); | ||
43 | *ind_blocks += tmp; | ||
44 | } | ||
45 | } | ||
46 | |||
17 | int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); | 47 | int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page); |
18 | int gfs2_block_map(struct inode *inode, sector_t lblock, struct buffer_head *bh, int create); | 48 | int gfs2_block_map(struct inode *inode, sector_t lblock, struct buffer_head *bh, int create); |
19 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); | 49 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); |
@@ -21,10 +51,6 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi | |||
21 | int gfs2_truncatei(struct gfs2_inode *ip, u64 size); | 51 | int gfs2_truncatei(struct gfs2_inode *ip, u64 size); |
22 | int gfs2_truncatei_resume(struct gfs2_inode *ip); | 52 | int gfs2_truncatei_resume(struct gfs2_inode *ip); |
23 | int gfs2_file_dealloc(struct gfs2_inode *ip); | 53 | int gfs2_file_dealloc(struct gfs2_inode *ip); |
24 | |||
25 | void gfs2_write_calc_reserv(struct gfs2_inode *ip, unsigned int len, | ||
26 | unsigned int *data_blocks, | ||
27 | unsigned int *ind_blocks); | ||
28 | int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, | 54 | int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset, |
29 | unsigned int len, int *alloc_required); | 55 | unsigned int len, int *alloc_required); |
30 | 56 | ||
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c deleted file mode 100644 index e51991947d2c..000000000000 --- a/fs/gfs2/daemon.c +++ /dev/null | |||
@@ -1,136 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #include <linux/sched.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/completion.h> | ||
14 | #include <linux/buffer_head.h> | ||
15 | #include <linux/kthread.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/gfs2_ondisk.h> | ||
18 | #include <linux/lm_interface.h> | ||
19 | #include <linux/freezer.h> | ||
20 | |||
21 | #include "gfs2.h" | ||
22 | #include "incore.h" | ||
23 | #include "daemon.h" | ||
24 | #include "glock.h" | ||
25 | #include "log.h" | ||
26 | #include "quota.h" | ||
27 | #include "recovery.h" | ||
28 | #include "super.h" | ||
29 | #include "util.h" | ||
30 | |||
31 | /* This uses schedule_timeout() instead of msleep() because it's good for | ||
32 | the daemons to wake up more often than the timeout when unmounting so | ||
33 | the user's unmount doesn't sit there forever. | ||
34 | |||
35 | The kthread functions used to start these daemons block and flush signals. */ | ||
36 | |||
37 | /** | ||
38 | * gfs2_glockd - Reclaim unused glock structures | ||
39 | * @sdp: Pointer to GFS2 superblock | ||
40 | * | ||
41 | * One or more of these daemons run, reclaiming glocks on sd_reclaim_list. | ||
42 | * Number of daemons can be set by user, with num_glockd mount option. | ||
43 | */ | ||
44 | |||
45 | int gfs2_glockd(void *data) | ||
46 | { | ||
47 | struct gfs2_sbd *sdp = data; | ||
48 | |||
49 | while (!kthread_should_stop()) { | ||
50 | while (atomic_read(&sdp->sd_reclaim_count)) | ||
51 | gfs2_reclaim_glock(sdp); | ||
52 | |||
53 | wait_event_interruptible(sdp->sd_reclaim_wq, | ||
54 | (atomic_read(&sdp->sd_reclaim_count) || | ||
55 | kthread_should_stop())); | ||
56 | if (freezing(current)) | ||
57 | refrigerator(); | ||
58 | } | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | /** | ||
64 | * gfs2_recoverd - Recover dead machine's journals | ||
65 | * @sdp: Pointer to GFS2 superblock | ||
66 | * | ||
67 | */ | ||
68 | |||
69 | int gfs2_recoverd(void *data) | ||
70 | { | ||
71 | struct gfs2_sbd *sdp = data; | ||
72 | unsigned long t; | ||
73 | |||
74 | while (!kthread_should_stop()) { | ||
75 | gfs2_check_journals(sdp); | ||
76 | t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ; | ||
77 | if (freezing(current)) | ||
78 | refrigerator(); | ||
79 | schedule_timeout_interruptible(t); | ||
80 | } | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /** | ||
86 | * gfs2_quotad - Write cached quota changes into the quota file | ||
87 | * @sdp: Pointer to GFS2 superblock | ||
88 | * | ||
89 | */ | ||
90 | |||
91 | int gfs2_quotad(void *data) | ||
92 | { | ||
93 | struct gfs2_sbd *sdp = data; | ||
94 | unsigned long t; | ||
95 | int error; | ||
96 | |||
97 | while (!kthread_should_stop()) { | ||
98 | /* Update the master statfs file */ | ||
99 | |||
100 | t = sdp->sd_statfs_sync_time + | ||
101 | gfs2_tune_get(sdp, gt_statfs_quantum) * HZ; | ||
102 | |||
103 | if (time_after_eq(jiffies, t)) { | ||
104 | error = gfs2_statfs_sync(sdp); | ||
105 | if (error && | ||
106 | error != -EROFS && | ||
107 | !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
108 | fs_err(sdp, "quotad: (1) error=%d\n", error); | ||
109 | sdp->sd_statfs_sync_time = jiffies; | ||
110 | } | ||
111 | |||
112 | /* Update quota file */ | ||
113 | |||
114 | t = sdp->sd_quota_sync_time + | ||
115 | gfs2_tune_get(sdp, gt_quota_quantum) * HZ; | ||
116 | |||
117 | if (time_after_eq(jiffies, t)) { | ||
118 | error = gfs2_quota_sync(sdp); | ||
119 | if (error && | ||
120 | error != -EROFS && | ||
121 | !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
122 | fs_err(sdp, "quotad: (2) error=%d\n", error); | ||
123 | sdp->sd_quota_sync_time = jiffies; | ||
124 | } | ||
125 | |||
126 | gfs2_quota_scan(sdp); | ||
127 | |||
128 | t = gfs2_tune_get(sdp, gt_quotad_secs) * HZ; | ||
129 | if (freezing(current)) | ||
130 | refrigerator(); | ||
131 | schedule_timeout_interruptible(t); | ||
132 | } | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
diff --git a/fs/gfs2/daemon.h b/fs/gfs2/daemon.h deleted file mode 100644 index 4be084fb6a62..000000000000 --- a/fs/gfs2/daemon.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __DAEMON_DOT_H__ | ||
11 | #define __DAEMON_DOT_H__ | ||
12 | |||
13 | int gfs2_glockd(void *data); | ||
14 | int gfs2_recoverd(void *data); | ||
15 | int gfs2_quotad(void *data); | ||
16 | |||
17 | #endif /* __DAEMON_DOT_H__ */ | ||
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index eed040d8ba3a..b7c8e5c70791 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -36,7 +36,7 @@ | |||
36 | * the block. In leaves, they begin at offset sizeof(struct gfs2_leaf) from the | 36 | * the block. In leaves, they begin at offset sizeof(struct gfs2_leaf) from the |
37 | * beginning of the leaf block. The dirents reside in leaves when | 37 | * beginning of the leaf block. The dirents reside in leaves when |
38 | * | 38 | * |
39 | * dip->i_di.di_flags & GFS2_DIF_EXHASH is true | 39 | * dip->i_diskflags & GFS2_DIF_EXHASH is true |
40 | * | 40 | * |
41 | * Otherwise, the dirents are "linear", within a single stuffed dinode block. | 41 | * Otherwise, the dirents are "linear", within a single stuffed dinode block. |
42 | * | 42 | * |
@@ -128,8 +128,8 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf, | |||
128 | 128 | ||
129 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 129 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
130 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); | 130 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); |
131 | if (ip->i_di.di_size < offset + size) | 131 | if (ip->i_disksize < offset + size) |
132 | ip->i_di.di_size = offset + size; | 132 | ip->i_disksize = offset + size; |
133 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 133 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
134 | gfs2_dinode_out(ip, dibh->b_data); | 134 | gfs2_dinode_out(ip, dibh->b_data); |
135 | 135 | ||
@@ -226,8 +226,8 @@ out: | |||
226 | if (error) | 226 | if (error) |
227 | return error; | 227 | return error; |
228 | 228 | ||
229 | if (ip->i_di.di_size < offset + copied) | 229 | if (ip->i_disksize < offset + copied) |
230 | ip->i_di.di_size = offset + copied; | 230 | ip->i_disksize = offset + copied; |
231 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 231 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
232 | 232 | ||
233 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 233 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
@@ -277,11 +277,11 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset, | |||
277 | int copied = 0; | 277 | int copied = 0; |
278 | int error = 0; | 278 | int error = 0; |
279 | 279 | ||
280 | if (offset >= ip->i_di.di_size) | 280 | if (offset >= ip->i_disksize) |
281 | return 0; | 281 | return 0; |
282 | 282 | ||
283 | if (offset + size > ip->i_di.di_size) | 283 | if (offset + size > ip->i_disksize) |
284 | size = ip->i_di.di_size - offset; | 284 | size = ip->i_disksize - offset; |
285 | 285 | ||
286 | if (!size) | 286 | if (!size) |
287 | return 0; | 287 | return 0; |
@@ -755,12 +755,12 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode, | |||
755 | struct gfs2_inode *ip = GFS2_I(inode); | 755 | struct gfs2_inode *ip = GFS2_I(inode); |
756 | int error; | 756 | int error; |
757 | 757 | ||
758 | if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { | 758 | if (ip->i_diskflags & GFS2_DIF_EXHASH) { |
759 | struct gfs2_leaf *leaf; | 759 | struct gfs2_leaf *leaf; |
760 | unsigned hsize = 1 << ip->i_depth; | 760 | unsigned hsize = 1 << ip->i_depth; |
761 | unsigned index; | 761 | unsigned index; |
762 | u64 ln; | 762 | u64 ln; |
763 | if (hsize * sizeof(u64) != ip->i_di.di_size) { | 763 | if (hsize * sizeof(u64) != ip->i_disksize) { |
764 | gfs2_consist_inode(ip); | 764 | gfs2_consist_inode(ip); |
765 | return ERR_PTR(-EIO); | 765 | return ERR_PTR(-EIO); |
766 | } | 766 | } |
@@ -858,8 +858,8 @@ static int dir_make_exhash(struct inode *inode) | |||
858 | return -ENOSPC; | 858 | return -ENOSPC; |
859 | bn = bh->b_blocknr; | 859 | bn = bh->b_blocknr; |
860 | 860 | ||
861 | gfs2_assert(sdp, dip->i_di.di_entries < (1 << 16)); | 861 | gfs2_assert(sdp, dip->i_entries < (1 << 16)); |
862 | leaf->lf_entries = cpu_to_be16(dip->i_di.di_entries); | 862 | leaf->lf_entries = cpu_to_be16(dip->i_entries); |
863 | 863 | ||
864 | /* Copy dirents */ | 864 | /* Copy dirents */ |
865 | 865 | ||
@@ -905,9 +905,9 @@ static int dir_make_exhash(struct inode *inode) | |||
905 | for (x = sdp->sd_hash_ptrs; x--; lp++) | 905 | for (x = sdp->sd_hash_ptrs; x--; lp++) |
906 | *lp = cpu_to_be64(bn); | 906 | *lp = cpu_to_be64(bn); |
907 | 907 | ||
908 | dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; | 908 | dip->i_disksize = sdp->sd_sb.sb_bsize / 2; |
909 | gfs2_add_inode_blocks(&dip->i_inode, 1); | 909 | gfs2_add_inode_blocks(&dip->i_inode, 1); |
910 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; | 910 | dip->i_diskflags |= GFS2_DIF_EXHASH; |
911 | 911 | ||
912 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; | 912 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; |
913 | dip->i_depth = y; | 913 | dip->i_depth = y; |
@@ -1082,7 +1082,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1082 | int error = 0; | 1082 | int error = 0; |
1083 | 1083 | ||
1084 | hsize = 1 << dip->i_depth; | 1084 | hsize = 1 << dip->i_depth; |
1085 | if (hsize * sizeof(u64) != dip->i_di.di_size) { | 1085 | if (hsize * sizeof(u64) != dip->i_disksize) { |
1086 | gfs2_consist_inode(dip); | 1086 | gfs2_consist_inode(dip); |
1087 | return -EIO; | 1087 | return -EIO; |
1088 | } | 1088 | } |
@@ -1091,7 +1091,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1091 | 1091 | ||
1092 | buf = kcalloc(3, sdp->sd_hash_bsize, GFP_NOFS | __GFP_NOFAIL); | 1092 | buf = kcalloc(3, sdp->sd_hash_bsize, GFP_NOFS | __GFP_NOFAIL); |
1093 | 1093 | ||
1094 | for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { | 1094 | for (block = dip->i_disksize >> sdp->sd_hash_bsize_shift; block--;) { |
1095 | error = gfs2_dir_read_data(dip, (char *)buf, | 1095 | error = gfs2_dir_read_data(dip, (char *)buf, |
1096 | block * sdp->sd_hash_bsize, | 1096 | block * sdp->sd_hash_bsize, |
1097 | sdp->sd_hash_bsize, 1); | 1097 | sdp->sd_hash_bsize, 1); |
@@ -1370,7 +1370,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1370 | unsigned depth = 0; | 1370 | unsigned depth = 0; |
1371 | 1371 | ||
1372 | hsize = 1 << dip->i_depth; | 1372 | hsize = 1 << dip->i_depth; |
1373 | if (hsize * sizeof(u64) != dip->i_di.di_size) { | 1373 | if (hsize * sizeof(u64) != dip->i_disksize) { |
1374 | gfs2_consist_inode(dip); | 1374 | gfs2_consist_inode(dip); |
1375 | return -EIO; | 1375 | return -EIO; |
1376 | } | 1376 | } |
@@ -1426,10 +1426,10 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | |||
1426 | int copied = 0; | 1426 | int copied = 0; |
1427 | int error; | 1427 | int error; |
1428 | 1428 | ||
1429 | if (!dip->i_di.di_entries) | 1429 | if (!dip->i_entries) |
1430 | return 0; | 1430 | return 0; |
1431 | 1431 | ||
1432 | if (dip->i_di.di_flags & GFS2_DIF_EXHASH) | 1432 | if (dip->i_diskflags & GFS2_DIF_EXHASH) |
1433 | return dir_e_read(inode, offset, opaque, filldir); | 1433 | return dir_e_read(inode, offset, opaque, filldir); |
1434 | 1434 | ||
1435 | if (!gfs2_is_stuffed(dip)) { | 1435 | if (!gfs2_is_stuffed(dip)) { |
@@ -1453,17 +1453,17 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque, | |||
1453 | error = PTR_ERR(dent); | 1453 | error = PTR_ERR(dent); |
1454 | goto out; | 1454 | goto out; |
1455 | } | 1455 | } |
1456 | if (dip->i_di.di_entries != g.offset) { | 1456 | if (dip->i_entries != g.offset) { |
1457 | fs_warn(sdp, "Number of entries corrupt in dir %llu, " | 1457 | fs_warn(sdp, "Number of entries corrupt in dir %llu, " |
1458 | "ip->i_di.di_entries (%u) != g.offset (%u)\n", | 1458 | "ip->i_entries (%u) != g.offset (%u)\n", |
1459 | (unsigned long long)dip->i_no_addr, | 1459 | (unsigned long long)dip->i_no_addr, |
1460 | dip->i_di.di_entries, | 1460 | dip->i_entries, |
1461 | g.offset); | 1461 | g.offset); |
1462 | error = -EIO; | 1462 | error = -EIO; |
1463 | goto out; | 1463 | goto out; |
1464 | } | 1464 | } |
1465 | error = do_filldir_main(dip, offset, opaque, filldir, darr, | 1465 | error = do_filldir_main(dip, offset, opaque, filldir, darr, |
1466 | dip->i_di.di_entries, &copied); | 1466 | dip->i_entries, &copied); |
1467 | out: | 1467 | out: |
1468 | kfree(darr); | 1468 | kfree(darr); |
1469 | } | 1469 | } |
@@ -1612,7 +1612,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1612 | dent = gfs2_init_dirent(inode, dent, name, bh); | 1612 | dent = gfs2_init_dirent(inode, dent, name, bh); |
1613 | gfs2_inum_out(nip, dent); | 1613 | gfs2_inum_out(nip, dent); |
1614 | dent->de_type = cpu_to_be16(type); | 1614 | dent->de_type = cpu_to_be16(type); |
1615 | if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { | 1615 | if (ip->i_diskflags & GFS2_DIF_EXHASH) { |
1616 | leaf = (struct gfs2_leaf *)bh->b_data; | 1616 | leaf = (struct gfs2_leaf *)bh->b_data; |
1617 | be16_add_cpu(&leaf->lf_entries, 1); | 1617 | be16_add_cpu(&leaf->lf_entries, 1); |
1618 | } | 1618 | } |
@@ -1621,14 +1621,14 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1621 | if (error) | 1621 | if (error) |
1622 | break; | 1622 | break; |
1623 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1623 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1624 | ip->i_di.di_entries++; | 1624 | ip->i_entries++; |
1625 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 1625 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1626 | gfs2_dinode_out(ip, bh->b_data); | 1626 | gfs2_dinode_out(ip, bh->b_data); |
1627 | brelse(bh); | 1627 | brelse(bh); |
1628 | error = 0; | 1628 | error = 0; |
1629 | break; | 1629 | break; |
1630 | } | 1630 | } |
1631 | if (!(ip->i_di.di_flags & GFS2_DIF_EXHASH)) { | 1631 | if (!(ip->i_diskflags & GFS2_DIF_EXHASH)) { |
1632 | error = dir_make_exhash(inode); | 1632 | error = dir_make_exhash(inode); |
1633 | if (error) | 1633 | if (error) |
1634 | break; | 1634 | break; |
@@ -1691,7 +1691,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1691 | } | 1691 | } |
1692 | 1692 | ||
1693 | dirent_del(dip, bh, prev, dent); | 1693 | dirent_del(dip, bh, prev, dent); |
1694 | if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { | 1694 | if (dip->i_diskflags & GFS2_DIF_EXHASH) { |
1695 | struct gfs2_leaf *leaf = (struct gfs2_leaf *)bh->b_data; | 1695 | struct gfs2_leaf *leaf = (struct gfs2_leaf *)bh->b_data; |
1696 | u16 entries = be16_to_cpu(leaf->lf_entries); | 1696 | u16 entries = be16_to_cpu(leaf->lf_entries); |
1697 | if (!entries) | 1697 | if (!entries) |
@@ -1704,10 +1704,10 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1704 | if (error) | 1704 | if (error) |
1705 | return error; | 1705 | return error; |
1706 | 1706 | ||
1707 | if (!dip->i_di.di_entries) | 1707 | if (!dip->i_entries) |
1708 | gfs2_consist_inode(dip); | 1708 | gfs2_consist_inode(dip); |
1709 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1709 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1710 | dip->i_di.di_entries--; | 1710 | dip->i_entries--; |
1711 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; | 1711 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; |
1712 | gfs2_dinode_out(dip, bh->b_data); | 1712 | gfs2_dinode_out(dip, bh->b_data); |
1713 | brelse(bh); | 1713 | brelse(bh); |
@@ -1748,7 +1748,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | |||
1748 | gfs2_inum_out(nip, dent); | 1748 | gfs2_inum_out(nip, dent); |
1749 | dent->de_type = cpu_to_be16(new_type); | 1749 | dent->de_type = cpu_to_be16(new_type); |
1750 | 1750 | ||
1751 | if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { | 1751 | if (dip->i_diskflags & GFS2_DIF_EXHASH) { |
1752 | brelse(bh); | 1752 | brelse(bh); |
1753 | error = gfs2_meta_inode_buffer(dip, &bh); | 1753 | error = gfs2_meta_inode_buffer(dip, &bh); |
1754 | if (error) | 1754 | if (error) |
@@ -1784,7 +1784,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1784 | int error = 0; | 1784 | int error = 0; |
1785 | 1785 | ||
1786 | hsize = 1 << dip->i_depth; | 1786 | hsize = 1 << dip->i_depth; |
1787 | if (hsize * sizeof(u64) != dip->i_di.di_size) { | 1787 | if (hsize * sizeof(u64) != dip->i_disksize) { |
1788 | gfs2_consist_inode(dip); | 1788 | gfs2_consist_inode(dip); |
1789 | return -EIO; | 1789 | return -EIO; |
1790 | } | 1790 | } |
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index 8a468cac9328..4f919440c3be 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #define __DIR_DOT_H__ | 11 | #define __DIR_DOT_H__ |
12 | 12 | ||
13 | #include <linux/dcache.h> | 13 | #include <linux/dcache.h> |
14 | #include <linux/crc32.h> | ||
14 | 15 | ||
15 | struct inode; | 16 | struct inode; |
16 | struct gfs2_inode; | 17 | struct gfs2_inode; |
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index e3f76f451b0a..0d1c76d906ae 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c | |||
@@ -114,11 +114,11 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | |||
114 | __be64 *eablk, *end; | 114 | __be64 *eablk, *end; |
115 | int error; | 115 | int error; |
116 | 116 | ||
117 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, &bh); | 117 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &bh); |
118 | if (error) | 118 | if (error) |
119 | return error; | 119 | return error; |
120 | 120 | ||
121 | if (!(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT)) { | 121 | if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT)) { |
122 | error = ea_foreach_i(ip, bh, ea_call, data); | 122 | error = ea_foreach_i(ip, bh, ea_call, data); |
123 | goto out; | 123 | goto out; |
124 | } | 124 | } |
@@ -414,7 +414,7 @@ int gfs2_ea_list(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
414 | if (error) | 414 | if (error) |
415 | return error; | 415 | return error; |
416 | 416 | ||
417 | if (ip->i_di.di_eattr) { | 417 | if (ip->i_eattr) { |
418 | struct ea_list ei = { .ei_er = er, .ei_size = 0 }; | 418 | struct ea_list ei = { .ei_er = er, .ei_size = 0 }; |
419 | 419 | ||
420 | error = ea_foreach(ip, ea_list_i, &ei); | 420 | error = ea_foreach(ip, ea_list_i, &ei); |
@@ -514,7 +514,7 @@ int gfs2_ea_get_i(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
514 | struct gfs2_ea_location el; | 514 | struct gfs2_ea_location el; |
515 | int error; | 515 | int error; |
516 | 516 | ||
517 | if (!ip->i_di.di_eattr) | 517 | if (!ip->i_eattr) |
518 | return -ENODATA; | 518 | return -ENODATA; |
519 | 519 | ||
520 | error = gfs2_ea_find(ip, er, &el); | 520 | error = gfs2_ea_find(ip, er, &el); |
@@ -741,7 +741,7 @@ static int ea_init_i(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
741 | if (error) | 741 | if (error) |
742 | return error; | 742 | return error; |
743 | 743 | ||
744 | ip->i_di.di_eattr = bh->b_blocknr; | 744 | ip->i_eattr = bh->b_blocknr; |
745 | error = ea_write(ip, GFS2_EA_BH2FIRST(bh), er); | 745 | error = ea_write(ip, GFS2_EA_BH2FIRST(bh), er); |
746 | 746 | ||
747 | brelse(bh); | 747 | brelse(bh); |
@@ -935,10 +935,10 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
935 | int error; | 935 | int error; |
936 | int mh_size = sizeof(struct gfs2_meta_header); | 936 | int mh_size = sizeof(struct gfs2_meta_header); |
937 | 937 | ||
938 | if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT) { | 938 | if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) { |
939 | __be64 *end; | 939 | __be64 *end; |
940 | 940 | ||
941 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, | 941 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, |
942 | &indbh); | 942 | &indbh); |
943 | if (error) | 943 | if (error) |
944 | return error; | 944 | return error; |
@@ -972,9 +972,9 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
972 | gfs2_buffer_clear_tail(indbh, mh_size); | 972 | gfs2_buffer_clear_tail(indbh, mh_size); |
973 | 973 | ||
974 | eablk = (__be64 *)(indbh->b_data + mh_size); | 974 | eablk = (__be64 *)(indbh->b_data + mh_size); |
975 | *eablk = cpu_to_be64(ip->i_di.di_eattr); | 975 | *eablk = cpu_to_be64(ip->i_eattr); |
976 | ip->i_di.di_eattr = blk; | 976 | ip->i_eattr = blk; |
977 | ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT; | 977 | ip->i_diskflags |= GFS2_DIF_EA_INDIRECT; |
978 | gfs2_add_inode_blocks(&ip->i_inode, 1); | 978 | gfs2_add_inode_blocks(&ip->i_inode, 1); |
979 | 979 | ||
980 | eablk++; | 980 | eablk++; |
@@ -1015,7 +1015,7 @@ static int ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
1015 | if (error) | 1015 | if (error) |
1016 | return error; | 1016 | return error; |
1017 | 1017 | ||
1018 | if (!(ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT)) | 1018 | if (!(ip->i_diskflags & GFS2_DIF_EA_INDIRECT)) |
1019 | blks++; | 1019 | blks++; |
1020 | if (GFS2_EAREQ_SIZE_STUFFED(er) > GFS2_SB(&ip->i_inode)->sd_jbsize) | 1020 | if (GFS2_EAREQ_SIZE_STUFFED(er) > GFS2_SB(&ip->i_inode)->sd_jbsize) |
1021 | blks += DIV_ROUND_UP(er->er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize); | 1021 | blks += DIV_ROUND_UP(er->er_data_len, GFS2_SB(&ip->i_inode)->sd_jbsize); |
@@ -1040,7 +1040,7 @@ int gfs2_ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
1040 | struct gfs2_ea_location el; | 1040 | struct gfs2_ea_location el; |
1041 | int error; | 1041 | int error; |
1042 | 1042 | ||
1043 | if (!ip->i_di.di_eattr) { | 1043 | if (!ip->i_eattr) { |
1044 | if (er->er_flags & XATTR_REPLACE) | 1044 | if (er->er_flags & XATTR_REPLACE) |
1045 | return -ENODATA; | 1045 | return -ENODATA; |
1046 | return ea_init(ip, er); | 1046 | return ea_init(ip, er); |
@@ -1051,7 +1051,7 @@ int gfs2_ea_set_i(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
1051 | return error; | 1051 | return error; |
1052 | 1052 | ||
1053 | if (el.el_ea) { | 1053 | if (el.el_ea) { |
1054 | if (ip->i_di.di_flags & GFS2_DIF_APPENDONLY) { | 1054 | if (ip->i_diskflags & GFS2_DIF_APPENDONLY) { |
1055 | brelse(el.el_bh); | 1055 | brelse(el.el_bh); |
1056 | return -EPERM; | 1056 | return -EPERM; |
1057 | } | 1057 | } |
@@ -1145,7 +1145,7 @@ int gfs2_ea_remove_i(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
1145 | struct gfs2_ea_location el; | 1145 | struct gfs2_ea_location el; |
1146 | int error; | 1146 | int error; |
1147 | 1147 | ||
1148 | if (!ip->i_di.di_eattr) | 1148 | if (!ip->i_eattr) |
1149 | return -ENODATA; | 1149 | return -ENODATA; |
1150 | 1150 | ||
1151 | error = gfs2_ea_find(ip, er, &el); | 1151 | error = gfs2_ea_find(ip, er, &el); |
@@ -1309,7 +1309,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1309 | 1309 | ||
1310 | memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); | 1310 | memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); |
1311 | 1311 | ||
1312 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, &indbh); | 1312 | error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh); |
1313 | if (error) | 1313 | if (error) |
1314 | return error; | 1314 | return error; |
1315 | 1315 | ||
@@ -1388,7 +1388,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1388 | if (bstart) | 1388 | if (bstart) |
1389 | gfs2_free_meta(ip, bstart, blen); | 1389 | gfs2_free_meta(ip, bstart, blen); |
1390 | 1390 | ||
1391 | ip->i_di.di_flags &= ~GFS2_DIF_EA_INDIRECT; | 1391 | ip->i_diskflags &= ~GFS2_DIF_EA_INDIRECT; |
1392 | 1392 | ||
1393 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1393 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1394 | if (!error) { | 1394 | if (!error) { |
@@ -1416,7 +1416,7 @@ static int ea_dealloc_block(struct gfs2_inode *ip) | |||
1416 | struct buffer_head *dibh; | 1416 | struct buffer_head *dibh; |
1417 | int error; | 1417 | int error; |
1418 | 1418 | ||
1419 | rgd = gfs2_blk2rgrpd(sdp, ip->i_di.di_eattr); | 1419 | rgd = gfs2_blk2rgrpd(sdp, ip->i_eattr); |
1420 | if (!rgd) { | 1420 | if (!rgd) { |
1421 | gfs2_consist_inode(ip); | 1421 | gfs2_consist_inode(ip); |
1422 | return -EIO; | 1422 | return -EIO; |
@@ -1432,9 +1432,9 @@ static int ea_dealloc_block(struct gfs2_inode *ip) | |||
1432 | if (error) | 1432 | if (error) |
1433 | goto out_gunlock; | 1433 | goto out_gunlock; |
1434 | 1434 | ||
1435 | gfs2_free_meta(ip, ip->i_di.di_eattr, 1); | 1435 | gfs2_free_meta(ip, ip->i_eattr, 1); |
1436 | 1436 | ||
1437 | ip->i_di.di_eattr = 0; | 1437 | ip->i_eattr = 0; |
1438 | gfs2_add_inode_blocks(&ip->i_inode, -1); | 1438 | gfs2_add_inode_blocks(&ip->i_inode, -1); |
1439 | 1439 | ||
1440 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1440 | error = gfs2_meta_inode_buffer(ip, &dibh); |
@@ -1479,7 +1479,7 @@ int gfs2_ea_dealloc(struct gfs2_inode *ip) | |||
1479 | if (error) | 1479 | if (error) |
1480 | goto out_rindex; | 1480 | goto out_rindex; |
1481 | 1481 | ||
1482 | if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT) { | 1482 | if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) { |
1483 | error = ea_dealloc_indirect(ip); | 1483 | error = ea_dealloc_indirect(ip); |
1484 | if (error) | 1484 | if (error) |
1485 | goto out_rindex; | 1485 | goto out_rindex; |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index c962283d4e7f..6b983aef785d 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "quota.h" | 40 | #include "quota.h" |
41 | #include "super.h" | 41 | #include "super.h" |
42 | #include "util.h" | 42 | #include "util.h" |
43 | #include "bmap.h" | ||
43 | 44 | ||
44 | struct gfs2_gl_hash_bucket { | 45 | struct gfs2_gl_hash_bucket { |
45 | struct hlist_head hb_list; | 46 | struct hlist_head hb_list; |
@@ -61,9 +62,10 @@ static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int | |||
61 | 62 | ||
62 | static DECLARE_RWSEM(gfs2_umount_flush_sem); | 63 | static DECLARE_RWSEM(gfs2_umount_flush_sem); |
63 | static struct dentry *gfs2_root; | 64 | static struct dentry *gfs2_root; |
64 | static struct task_struct *scand_process; | ||
65 | static unsigned int scand_secs = 5; | ||
66 | static struct workqueue_struct *glock_workqueue; | 65 | static struct workqueue_struct *glock_workqueue; |
66 | static LIST_HEAD(lru_list); | ||
67 | static atomic_t lru_count = ATOMIC_INIT(0); | ||
68 | static DEFINE_SPINLOCK(lru_lock); | ||
67 | 69 | ||
68 | #define GFS2_GL_HASH_SHIFT 15 | 70 | #define GFS2_GL_HASH_SHIFT 15 |
69 | #define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) | 71 | #define GFS2_GL_HASH_SIZE (1 << GFS2_GL_HASH_SHIFT) |
@@ -174,6 +176,22 @@ static void gfs2_glock_hold(struct gfs2_glock *gl) | |||
174 | } | 176 | } |
175 | 177 | ||
176 | /** | 178 | /** |
179 | * gfs2_glock_schedule_for_reclaim - Add a glock to the reclaim list | ||
180 | * @gl: the glock | ||
181 | * | ||
182 | */ | ||
183 | |||
184 | static void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl) | ||
185 | { | ||
186 | spin_lock(&lru_lock); | ||
187 | if (list_empty(&gl->gl_lru) && gl->gl_state != LM_ST_UNLOCKED) { | ||
188 | list_add_tail(&gl->gl_lru, &lru_list); | ||
189 | atomic_inc(&lru_count); | ||
190 | } | ||
191 | spin_unlock(&lru_lock); | ||
192 | } | ||
193 | |||
194 | /** | ||
177 | * gfs2_glock_put() - Decrement reference count on glock | 195 | * gfs2_glock_put() - Decrement reference count on glock |
178 | * @gl: The glock to put | 196 | * @gl: The glock to put |
179 | * | 197 | * |
@@ -187,14 +205,23 @@ int gfs2_glock_put(struct gfs2_glock *gl) | |||
187 | if (atomic_dec_and_test(&gl->gl_ref)) { | 205 | if (atomic_dec_and_test(&gl->gl_ref)) { |
188 | hlist_del(&gl->gl_list); | 206 | hlist_del(&gl->gl_list); |
189 | write_unlock(gl_lock_addr(gl->gl_hash)); | 207 | write_unlock(gl_lock_addr(gl->gl_hash)); |
208 | spin_lock(&lru_lock); | ||
209 | if (!list_empty(&gl->gl_lru)) { | ||
210 | list_del_init(&gl->gl_lru); | ||
211 | atomic_dec(&lru_count); | ||
212 | } | ||
213 | spin_unlock(&lru_lock); | ||
190 | GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_UNLOCKED); | 214 | GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_UNLOCKED); |
191 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_reclaim)); | 215 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_lru)); |
192 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); | 216 | GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders)); |
193 | glock_free(gl); | 217 | glock_free(gl); |
194 | rv = 1; | 218 | rv = 1; |
195 | goto out; | 219 | goto out; |
196 | } | 220 | } |
197 | write_unlock(gl_lock_addr(gl->gl_hash)); | 221 | write_unlock(gl_lock_addr(gl->gl_hash)); |
222 | /* 1 for being hashed, 1 for having state != LM_ST_UNLOCKED */ | ||
223 | if (atomic_read(&gl->gl_ref) == 2) | ||
224 | gfs2_glock_schedule_for_reclaim(gl); | ||
198 | out: | 225 | out: |
199 | return rv; | 226 | return rv; |
200 | } | 227 | } |
@@ -289,10 +316,13 @@ static void gfs2_holder_wake(struct gfs2_holder *gh) | |||
289 | * do_promote - promote as many requests as possible on the current queue | 316 | * do_promote - promote as many requests as possible on the current queue |
290 | * @gl: The glock | 317 | * @gl: The glock |
291 | * | 318 | * |
292 | * Returns: true if there is a blocked holder at the head of the list | 319 | * Returns: 1 if there is a blocked holder at the head of the list, or 2 |
320 | * if a type specific operation is underway. | ||
293 | */ | 321 | */ |
294 | 322 | ||
295 | static int do_promote(struct gfs2_glock *gl) | 323 | static int do_promote(struct gfs2_glock *gl) |
324 | __releases(&gl->gl_spin) | ||
325 | __acquires(&gl->gl_spin) | ||
296 | { | 326 | { |
297 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 327 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
298 | struct gfs2_holder *gh, *tmp; | 328 | struct gfs2_holder *gh, *tmp; |
@@ -310,6 +340,8 @@ restart: | |||
310 | ret = glops->go_lock(gh); | 340 | ret = glops->go_lock(gh); |
311 | spin_lock(&gl->gl_spin); | 341 | spin_lock(&gl->gl_spin); |
312 | if (ret) { | 342 | if (ret) { |
343 | if (ret == 1) | ||
344 | return 2; | ||
313 | gh->gh_error = ret; | 345 | gh->gh_error = ret; |
314 | list_del_init(&gh->gh_list); | 346 | list_del_init(&gh->gh_list); |
315 | gfs2_holder_wake(gh); | 347 | gfs2_holder_wake(gh); |
@@ -414,6 +446,7 @@ static void finish_xmote(struct gfs2_glock *gl, unsigned int ret) | |||
414 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 446 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
415 | struct gfs2_holder *gh; | 447 | struct gfs2_holder *gh; |
416 | unsigned state = ret & LM_OUT_ST_MASK; | 448 | unsigned state = ret & LM_OUT_ST_MASK; |
449 | int rv; | ||
417 | 450 | ||
418 | spin_lock(&gl->gl_spin); | 451 | spin_lock(&gl->gl_spin); |
419 | state_change(gl, state); | 452 | state_change(gl, state); |
@@ -468,7 +501,6 @@ retry: | |||
468 | gfs2_demote_wake(gl); | 501 | gfs2_demote_wake(gl); |
469 | if (state != LM_ST_UNLOCKED) { | 502 | if (state != LM_ST_UNLOCKED) { |
470 | if (glops->go_xmote_bh) { | 503 | if (glops->go_xmote_bh) { |
471 | int rv; | ||
472 | spin_unlock(&gl->gl_spin); | 504 | spin_unlock(&gl->gl_spin); |
473 | rv = glops->go_xmote_bh(gl, gh); | 505 | rv = glops->go_xmote_bh(gl, gh); |
474 | if (rv == -EAGAIN) | 506 | if (rv == -EAGAIN) |
@@ -479,10 +511,13 @@ retry: | |||
479 | goto out; | 511 | goto out; |
480 | } | 512 | } |
481 | } | 513 | } |
482 | do_promote(gl); | 514 | rv = do_promote(gl); |
515 | if (rv == 2) | ||
516 | goto out_locked; | ||
483 | } | 517 | } |
484 | out: | 518 | out: |
485 | clear_bit(GLF_LOCK, &gl->gl_flags); | 519 | clear_bit(GLF_LOCK, &gl->gl_flags); |
520 | out_locked: | ||
486 | spin_unlock(&gl->gl_spin); | 521 | spin_unlock(&gl->gl_spin); |
487 | gfs2_glock_put(gl); | 522 | gfs2_glock_put(gl); |
488 | } | 523 | } |
@@ -511,6 +546,8 @@ static unsigned int gfs2_lm_lock(struct gfs2_sbd *sdp, void *lock, | |||
511 | */ | 546 | */ |
512 | 547 | ||
513 | static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target) | 548 | static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target) |
549 | __releases(&gl->gl_spin) | ||
550 | __acquires(&gl->gl_spin) | ||
514 | { | 551 | { |
515 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 552 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
516 | struct gfs2_sbd *sdp = gl->gl_sbd; | 553 | struct gfs2_sbd *sdp = gl->gl_sbd; |
@@ -576,8 +613,11 @@ static inline struct gfs2_holder *find_first_holder(const struct gfs2_glock *gl) | |||
576 | */ | 613 | */ |
577 | 614 | ||
578 | static void run_queue(struct gfs2_glock *gl, const int nonblock) | 615 | static void run_queue(struct gfs2_glock *gl, const int nonblock) |
616 | __releases(&gl->gl_spin) | ||
617 | __acquires(&gl->gl_spin) | ||
579 | { | 618 | { |
580 | struct gfs2_holder *gh = NULL; | 619 | struct gfs2_holder *gh = NULL; |
620 | int ret; | ||
581 | 621 | ||
582 | if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) | 622 | if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) |
583 | return; | 623 | return; |
@@ -596,8 +636,11 @@ static void run_queue(struct gfs2_glock *gl, const int nonblock) | |||
596 | } else { | 636 | } else { |
597 | if (test_bit(GLF_DEMOTE, &gl->gl_flags)) | 637 | if (test_bit(GLF_DEMOTE, &gl->gl_flags)) |
598 | gfs2_demote_wake(gl); | 638 | gfs2_demote_wake(gl); |
599 | if (do_promote(gl) == 0) | 639 | ret = do_promote(gl); |
640 | if (ret == 0) | ||
600 | goto out; | 641 | goto out; |
642 | if (ret == 2) | ||
643 | return; | ||
601 | gh = find_first_waiter(gl); | 644 | gh = find_first_waiter(gl); |
602 | gl->gl_target = gh->gh_state; | 645 | gl->gl_target = gh->gh_state; |
603 | if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) | 646 | if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) |
@@ -820,7 +863,7 @@ static void wait_on_demote(struct gfs2_glock *gl) | |||
820 | */ | 863 | */ |
821 | 864 | ||
822 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, | 865 | static void handle_callback(struct gfs2_glock *gl, unsigned int state, |
823 | int remote, unsigned long delay) | 866 | unsigned long delay) |
824 | { | 867 | { |
825 | int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE; | 868 | int bit = delay ? GLF_PENDING_DEMOTE : GLF_DEMOTE; |
826 | 869 | ||
@@ -828,9 +871,6 @@ static void handle_callback(struct gfs2_glock *gl, unsigned int state, | |||
828 | if (gl->gl_demote_state == LM_ST_EXCLUSIVE) { | 871 | if (gl->gl_demote_state == LM_ST_EXCLUSIVE) { |
829 | gl->gl_demote_state = state; | 872 | gl->gl_demote_state = state; |
830 | gl->gl_demote_time = jiffies; | 873 | gl->gl_demote_time = jiffies; |
831 | if (remote && gl->gl_ops->go_type == LM_TYPE_IOPEN && | ||
832 | gl->gl_object) | ||
833 | gfs2_glock_schedule_for_reclaim(gl); | ||
834 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED && | 874 | } else if (gl->gl_demote_state != LM_ST_UNLOCKED && |
835 | gl->gl_demote_state != state) { | 875 | gl->gl_demote_state != state) { |
836 | gl->gl_demote_state = LM_ST_UNLOCKED; | 876 | gl->gl_demote_state = LM_ST_UNLOCKED; |
@@ -877,6 +917,8 @@ void gfs2_print_dbg(struct seq_file *seq, const char *fmt, ...) | |||
877 | */ | 917 | */ |
878 | 918 | ||
879 | static inline void add_to_queue(struct gfs2_holder *gh) | 919 | static inline void add_to_queue(struct gfs2_holder *gh) |
920 | __releases(&gl->gl_spin) | ||
921 | __acquires(&gl->gl_spin) | ||
880 | { | 922 | { |
881 | struct gfs2_glock *gl = gh->gh_gl; | 923 | struct gfs2_glock *gl = gh->gh_gl; |
882 | struct gfs2_sbd *sdp = gl->gl_sbd; | 924 | struct gfs2_sbd *sdp = gl->gl_sbd; |
@@ -998,7 +1040,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh) | |||
998 | 1040 | ||
999 | spin_lock(&gl->gl_spin); | 1041 | spin_lock(&gl->gl_spin); |
1000 | if (gh->gh_flags & GL_NOCACHE) | 1042 | if (gh->gh_flags & GL_NOCACHE) |
1001 | handle_callback(gl, LM_ST_UNLOCKED, 0, 0); | 1043 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1002 | 1044 | ||
1003 | list_del_init(&gh->gh_list); | 1045 | list_del_init(&gh->gh_list); |
1004 | if (find_first_holder(gl) == NULL) { | 1046 | if (find_first_holder(gl) == NULL) { |
@@ -1269,12 +1311,26 @@ static void blocking_cb(struct gfs2_sbd *sdp, struct lm_lockname *name, | |||
1269 | delay = gl->gl_ops->go_min_hold_time; | 1311 | delay = gl->gl_ops->go_min_hold_time; |
1270 | 1312 | ||
1271 | spin_lock(&gl->gl_spin); | 1313 | spin_lock(&gl->gl_spin); |
1272 | handle_callback(gl, state, 1, delay); | 1314 | handle_callback(gl, state, delay); |
1273 | spin_unlock(&gl->gl_spin); | 1315 | spin_unlock(&gl->gl_spin); |
1274 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) | 1316 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, delay) == 0) |
1275 | gfs2_glock_put(gl); | 1317 | gfs2_glock_put(gl); |
1276 | } | 1318 | } |
1277 | 1319 | ||
1320 | static void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid) | ||
1321 | { | ||
1322 | struct gfs2_jdesc *jd; | ||
1323 | |||
1324 | spin_lock(&sdp->sd_jindex_spin); | ||
1325 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
1326 | if (jd->jd_jid != jid) | ||
1327 | continue; | ||
1328 | jd->jd_dirty = 1; | ||
1329 | break; | ||
1330 | } | ||
1331 | spin_unlock(&sdp->sd_jindex_spin); | ||
1332 | } | ||
1333 | |||
1278 | /** | 1334 | /** |
1279 | * gfs2_glock_cb - Callback used by locking module | 1335 | * gfs2_glock_cb - Callback used by locking module |
1280 | * @sdp: Pointer to the superblock | 1336 | * @sdp: Pointer to the superblock |
@@ -1338,80 +1394,83 @@ void gfs2_glock_cb(void *cb_data, unsigned int type, void *data) | |||
1338 | * Returns: 1 if it's ok | 1394 | * Returns: 1 if it's ok |
1339 | */ | 1395 | */ |
1340 | 1396 | ||
1341 | static int demote_ok(struct gfs2_glock *gl) | 1397 | static int demote_ok(const struct gfs2_glock *gl) |
1342 | { | 1398 | { |
1343 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 1399 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
1344 | int demote = 1; | ||
1345 | |||
1346 | if (test_bit(GLF_STICKY, &gl->gl_flags)) | ||
1347 | demote = 0; | ||
1348 | else if (glops->go_demote_ok) | ||
1349 | demote = glops->go_demote_ok(gl); | ||
1350 | |||
1351 | return demote; | ||
1352 | } | ||
1353 | |||
1354 | /** | ||
1355 | * gfs2_glock_schedule_for_reclaim - Add a glock to the reclaim list | ||
1356 | * @gl: the glock | ||
1357 | * | ||
1358 | */ | ||
1359 | |||
1360 | void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl) | ||
1361 | { | ||
1362 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
1363 | 1400 | ||
1364 | spin_lock(&sdp->sd_reclaim_lock); | 1401 | if (gl->gl_state == LM_ST_UNLOCKED) |
1365 | if (list_empty(&gl->gl_reclaim)) { | 1402 | return 0; |
1366 | gfs2_glock_hold(gl); | 1403 | if (!list_empty(&gl->gl_holders)) |
1367 | list_add(&gl->gl_reclaim, &sdp->sd_reclaim_list); | 1404 | return 0; |
1368 | atomic_inc(&sdp->sd_reclaim_count); | 1405 | if (glops->go_demote_ok) |
1369 | spin_unlock(&sdp->sd_reclaim_lock); | 1406 | return glops->go_demote_ok(gl); |
1370 | wake_up(&sdp->sd_reclaim_wq); | 1407 | return 1; |
1371 | } else | ||
1372 | spin_unlock(&sdp->sd_reclaim_lock); | ||
1373 | } | 1408 | } |
1374 | 1409 | ||
1375 | /** | ||
1376 | * gfs2_reclaim_glock - process the next glock on the filesystem's reclaim list | ||
1377 | * @sdp: the filesystem | ||
1378 | * | ||
1379 | * Called from gfs2_glockd() glock reclaim daemon, or when promoting a | ||
1380 | * different glock and we notice that there are a lot of glocks in the | ||
1381 | * reclaim list. | ||
1382 | * | ||
1383 | */ | ||
1384 | 1410 | ||
1385 | void gfs2_reclaim_glock(struct gfs2_sbd *sdp) | 1411 | static int gfs2_shrink_glock_memory(int nr, gfp_t gfp_mask) |
1386 | { | 1412 | { |
1387 | struct gfs2_glock *gl; | 1413 | struct gfs2_glock *gl; |
1388 | int done_callback = 0; | 1414 | int may_demote; |
1415 | int nr_skipped = 0; | ||
1416 | int got_ref = 0; | ||
1417 | LIST_HEAD(skipped); | ||
1389 | 1418 | ||
1390 | spin_lock(&sdp->sd_reclaim_lock); | 1419 | if (nr == 0) |
1391 | if (list_empty(&sdp->sd_reclaim_list)) { | 1420 | goto out; |
1392 | spin_unlock(&sdp->sd_reclaim_lock); | ||
1393 | return; | ||
1394 | } | ||
1395 | gl = list_entry(sdp->sd_reclaim_list.next, | ||
1396 | struct gfs2_glock, gl_reclaim); | ||
1397 | list_del_init(&gl->gl_reclaim); | ||
1398 | spin_unlock(&sdp->sd_reclaim_lock); | ||
1399 | 1421 | ||
1400 | atomic_dec(&sdp->sd_reclaim_count); | 1422 | if (!(gfp_mask & __GFP_FS)) |
1401 | atomic_inc(&sdp->sd_reclaimed); | 1423 | return -1; |
1402 | 1424 | ||
1403 | spin_lock(&gl->gl_spin); | 1425 | spin_lock(&lru_lock); |
1404 | if (find_first_holder(gl) == NULL && | 1426 | while(nr && !list_empty(&lru_list)) { |
1405 | gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) { | 1427 | gl = list_entry(lru_list.next, struct gfs2_glock, gl_lru); |
1406 | handle_callback(gl, LM_ST_UNLOCKED, 0, 0); | 1428 | list_del_init(&gl->gl_lru); |
1407 | done_callback = 1; | 1429 | atomic_dec(&lru_count); |
1430 | |||
1431 | /* Test for being demotable */ | ||
1432 | if (!test_and_set_bit(GLF_LOCK, &gl->gl_flags)) { | ||
1433 | gfs2_glock_hold(gl); | ||
1434 | got_ref = 1; | ||
1435 | spin_unlock(&lru_lock); | ||
1436 | spin_lock(&gl->gl_spin); | ||
1437 | may_demote = demote_ok(gl); | ||
1438 | spin_unlock(&gl->gl_spin); | ||
1439 | clear_bit(GLF_LOCK, &gl->gl_flags); | ||
1440 | if (may_demote) { | ||
1441 | handle_callback(gl, LM_ST_UNLOCKED, 0); | ||
1442 | nr--; | ||
1443 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | ||
1444 | gfs2_glock_put(gl); | ||
1445 | } | ||
1446 | spin_lock(&lru_lock); | ||
1447 | if (may_demote) | ||
1448 | continue; | ||
1449 | } | ||
1450 | if (list_empty(&gl->gl_lru) && | ||
1451 | (atomic_read(&gl->gl_ref) <= (2 + got_ref))) { | ||
1452 | nr_skipped++; | ||
1453 | list_add(&gl->gl_lru, &skipped); | ||
1454 | } | ||
1455 | if (got_ref) { | ||
1456 | spin_unlock(&lru_lock); | ||
1457 | gfs2_glock_put(gl); | ||
1458 | spin_lock(&lru_lock); | ||
1459 | got_ref = 0; | ||
1460 | } | ||
1408 | } | 1461 | } |
1409 | spin_unlock(&gl->gl_spin); | 1462 | list_splice(&skipped, &lru_list); |
1410 | if (!done_callback || | 1463 | atomic_add(nr_skipped, &lru_count); |
1411 | queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 1464 | spin_unlock(&lru_lock); |
1412 | gfs2_glock_put(gl); | 1465 | out: |
1466 | return (atomic_read(&lru_count) / 100) * sysctl_vfs_cache_pressure; | ||
1413 | } | 1467 | } |
1414 | 1468 | ||
1469 | static struct shrinker glock_shrinker = { | ||
1470 | .shrink = gfs2_shrink_glock_memory, | ||
1471 | .seeks = DEFAULT_SEEKS, | ||
1472 | }; | ||
1473 | |||
1415 | /** | 1474 | /** |
1416 | * examine_bucket - Call a function for glock in a hash bucket | 1475 | * examine_bucket - Call a function for glock in a hash bucket |
1417 | * @examiner: the function | 1476 | * @examiner: the function |
@@ -1457,26 +1516,6 @@ out: | |||
1457 | } | 1516 | } |
1458 | 1517 | ||
1459 | /** | 1518 | /** |
1460 | * scan_glock - look at a glock and see if we can reclaim it | ||
1461 | * @gl: the glock to look at | ||
1462 | * | ||
1463 | */ | ||
1464 | |||
1465 | static void scan_glock(struct gfs2_glock *gl) | ||
1466 | { | ||
1467 | if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) | ||
1468 | return; | ||
1469 | if (test_bit(GLF_LOCK, &gl->gl_flags)) | ||
1470 | return; | ||
1471 | |||
1472 | spin_lock(&gl->gl_spin); | ||
1473 | if (find_first_holder(gl) == NULL && | ||
1474 | gl->gl_state != LM_ST_UNLOCKED && demote_ok(gl)) | ||
1475 | gfs2_glock_schedule_for_reclaim(gl); | ||
1476 | spin_unlock(&gl->gl_spin); | ||
1477 | } | ||
1478 | |||
1479 | /** | ||
1480 | * clear_glock - look at a glock and see if we can free it from glock cache | 1519 | * clear_glock - look at a glock and see if we can free it from glock cache |
1481 | * @gl: the glock to look at | 1520 | * @gl: the glock to look at |
1482 | * | 1521 | * |
@@ -1484,23 +1523,16 @@ static void scan_glock(struct gfs2_glock *gl) | |||
1484 | 1523 | ||
1485 | static void clear_glock(struct gfs2_glock *gl) | 1524 | static void clear_glock(struct gfs2_glock *gl) |
1486 | { | 1525 | { |
1487 | struct gfs2_sbd *sdp = gl->gl_sbd; | 1526 | spin_lock(&lru_lock); |
1488 | int released; | 1527 | if (!list_empty(&gl->gl_lru)) { |
1489 | 1528 | list_del_init(&gl->gl_lru); | |
1490 | spin_lock(&sdp->sd_reclaim_lock); | 1529 | atomic_dec(&lru_count); |
1491 | if (!list_empty(&gl->gl_reclaim)) { | ||
1492 | list_del_init(&gl->gl_reclaim); | ||
1493 | atomic_dec(&sdp->sd_reclaim_count); | ||
1494 | spin_unlock(&sdp->sd_reclaim_lock); | ||
1495 | released = gfs2_glock_put(gl); | ||
1496 | gfs2_assert(sdp, !released); | ||
1497 | } else { | ||
1498 | spin_unlock(&sdp->sd_reclaim_lock); | ||
1499 | } | 1530 | } |
1531 | spin_unlock(&lru_lock); | ||
1500 | 1532 | ||
1501 | spin_lock(&gl->gl_spin); | 1533 | spin_lock(&gl->gl_spin); |
1502 | if (find_first_holder(gl) == NULL && gl->gl_state != LM_ST_UNLOCKED) | 1534 | if (find_first_holder(gl) == NULL && gl->gl_state != LM_ST_UNLOCKED) |
1503 | handle_callback(gl, LM_ST_UNLOCKED, 0, 0); | 1535 | handle_callback(gl, LM_ST_UNLOCKED, 0); |
1504 | spin_unlock(&gl->gl_spin); | 1536 | spin_unlock(&gl->gl_spin); |
1505 | gfs2_glock_hold(gl); | 1537 | gfs2_glock_hold(gl); |
1506 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) | 1538 | if (queue_delayed_work(glock_workqueue, &gl->gl_work, 0) == 0) |
@@ -1548,6 +1580,20 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp) | |||
1548 | } | 1580 | } |
1549 | } | 1581 | } |
1550 | 1582 | ||
1583 | void gfs2_glock_finish_truncate(struct gfs2_inode *ip) | ||
1584 | { | ||
1585 | struct gfs2_glock *gl = ip->i_gl; | ||
1586 | int ret; | ||
1587 | |||
1588 | ret = gfs2_truncatei_resume(ip); | ||
1589 | gfs2_assert_withdraw(gl->gl_sbd, ret == 0); | ||
1590 | |||
1591 | spin_lock(&gl->gl_spin); | ||
1592 | clear_bit(GLF_LOCK, &gl->gl_flags); | ||
1593 | run_queue(gl, 1); | ||
1594 | spin_unlock(&gl->gl_spin); | ||
1595 | } | ||
1596 | |||
1551 | static const char *state2str(unsigned state) | 1597 | static const char *state2str(unsigned state) |
1552 | { | 1598 | { |
1553 | switch(state) { | 1599 | switch(state) { |
@@ -1623,8 +1669,6 @@ static const char *gflags2str(char *buf, const unsigned long *gflags) | |||
1623 | char *p = buf; | 1669 | char *p = buf; |
1624 | if (test_bit(GLF_LOCK, gflags)) | 1670 | if (test_bit(GLF_LOCK, gflags)) |
1625 | *p++ = 'l'; | 1671 | *p++ = 'l'; |
1626 | if (test_bit(GLF_STICKY, gflags)) | ||
1627 | *p++ = 's'; | ||
1628 | if (test_bit(GLF_DEMOTE, gflags)) | 1672 | if (test_bit(GLF_DEMOTE, gflags)) |
1629 | *p++ = 'D'; | 1673 | *p++ = 'D'; |
1630 | if (test_bit(GLF_PENDING_DEMOTE, gflags)) | 1674 | if (test_bit(GLF_PENDING_DEMOTE, gflags)) |
@@ -1743,34 +1787,6 @@ static int gfs2_dump_lockstate(struct gfs2_sbd *sdp) | |||
1743 | return error; | 1787 | return error; |
1744 | } | 1788 | } |
1745 | 1789 | ||
1746 | /** | ||
1747 | * gfs2_scand - Look for cached glocks and inodes to toss from memory | ||
1748 | * @sdp: Pointer to GFS2 superblock | ||
1749 | * | ||
1750 | * One of these daemons runs, finding candidates to add to sd_reclaim_list. | ||
1751 | * See gfs2_glockd() | ||
1752 | */ | ||
1753 | |||
1754 | static int gfs2_scand(void *data) | ||
1755 | { | ||
1756 | unsigned x; | ||
1757 | unsigned delay; | ||
1758 | |||
1759 | while (!kthread_should_stop()) { | ||
1760 | for (x = 0; x < GFS2_GL_HASH_SIZE; x++) | ||
1761 | examine_bucket(scan_glock, NULL, x); | ||
1762 | if (freezing(current)) | ||
1763 | refrigerator(); | ||
1764 | delay = scand_secs; | ||
1765 | if (delay < 1) | ||
1766 | delay = 1; | ||
1767 | schedule_timeout_interruptible(delay * HZ); | ||
1768 | } | ||
1769 | |||
1770 | return 0; | ||
1771 | } | ||
1772 | |||
1773 | |||
1774 | 1790 | ||
1775 | int __init gfs2_glock_init(void) | 1791 | int __init gfs2_glock_init(void) |
1776 | { | 1792 | { |
@@ -1784,28 +1800,21 @@ int __init gfs2_glock_init(void) | |||
1784 | } | 1800 | } |
1785 | #endif | 1801 | #endif |
1786 | 1802 | ||
1787 | scand_process = kthread_run(gfs2_scand, NULL, "gfs2_scand"); | ||
1788 | if (IS_ERR(scand_process)) | ||
1789 | return PTR_ERR(scand_process); | ||
1790 | |||
1791 | glock_workqueue = create_workqueue("glock_workqueue"); | 1803 | glock_workqueue = create_workqueue("glock_workqueue"); |
1792 | if (IS_ERR(glock_workqueue)) { | 1804 | if (IS_ERR(glock_workqueue)) |
1793 | kthread_stop(scand_process); | ||
1794 | return PTR_ERR(glock_workqueue); | 1805 | return PTR_ERR(glock_workqueue); |
1795 | } | 1806 | |
1807 | register_shrinker(&glock_shrinker); | ||
1796 | 1808 | ||
1797 | return 0; | 1809 | return 0; |
1798 | } | 1810 | } |
1799 | 1811 | ||
1800 | void gfs2_glock_exit(void) | 1812 | void gfs2_glock_exit(void) |
1801 | { | 1813 | { |
1814 | unregister_shrinker(&glock_shrinker); | ||
1802 | destroy_workqueue(glock_workqueue); | 1815 | destroy_workqueue(glock_workqueue); |
1803 | kthread_stop(scand_process); | ||
1804 | } | 1816 | } |
1805 | 1817 | ||
1806 | module_param(scand_secs, uint, S_IRUGO|S_IWUSR); | ||
1807 | MODULE_PARM_DESC(scand_secs, "The number of seconds between scand runs"); | ||
1808 | |||
1809 | static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) | 1818 | static int gfs2_glock_iter_next(struct gfs2_glock_iter *gi) |
1810 | { | 1819 | { |
1811 | struct gfs2_glock *gl; | 1820 | struct gfs2_glock *gl; |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 695c6b193611..543ec7ecfbda 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -129,9 +129,9 @@ int gfs2_lvb_hold(struct gfs2_glock *gl); | |||
129 | void gfs2_lvb_unhold(struct gfs2_glock *gl); | 129 | void gfs2_lvb_unhold(struct gfs2_glock *gl); |
130 | 130 | ||
131 | void gfs2_glock_cb(void *cb_data, unsigned int type, void *data); | 131 | void gfs2_glock_cb(void *cb_data, unsigned int type, void *data); |
132 | void gfs2_glock_schedule_for_reclaim(struct gfs2_glock *gl); | ||
133 | void gfs2_reclaim_glock(struct gfs2_sbd *sdp); | 132 | void gfs2_reclaim_glock(struct gfs2_sbd *sdp); |
134 | void gfs2_gl_hash_clear(struct gfs2_sbd *sdp); | 133 | void gfs2_gl_hash_clear(struct gfs2_sbd *sdp); |
134 | void gfs2_glock_finish_truncate(struct gfs2_inode *ip); | ||
135 | 135 | ||
136 | int __init gfs2_glock_init(void); | 136 | int __init gfs2_glock_init(void); |
137 | void gfs2_glock_exit(void); | 137 | void gfs2_glock_exit(void); |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index c6c318c2a0f6..8522d3aa64fc 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -201,19 +201,12 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) | |||
201 | * Returns: 1 if it's ok | 201 | * Returns: 1 if it's ok |
202 | */ | 202 | */ |
203 | 203 | ||
204 | static int inode_go_demote_ok(struct gfs2_glock *gl) | 204 | static int inode_go_demote_ok(const struct gfs2_glock *gl) |
205 | { | 205 | { |
206 | struct gfs2_sbd *sdp = gl->gl_sbd; | 206 | struct gfs2_sbd *sdp = gl->gl_sbd; |
207 | int demote = 0; | 207 | if (sdp->sd_jindex == gl->gl_object || sdp->sd_rindex == gl->gl_object) |
208 | 208 | return 0; | |
209 | if (!gl->gl_object && !gl->gl_aspace->i_mapping->nrpages) | 209 | return 1; |
210 | demote = 1; | ||
211 | else if (!sdp->sd_args.ar_localcaching && | ||
212 | time_after_eq(jiffies, gl->gl_stamp + | ||
213 | gfs2_tune_get(sdp, gt_demote_secs) * HZ)) | ||
214 | demote = 1; | ||
215 | |||
216 | return demote; | ||
217 | } | 210 | } |
218 | 211 | ||
219 | /** | 212 | /** |
@@ -227,6 +220,7 @@ static int inode_go_demote_ok(struct gfs2_glock *gl) | |||
227 | static int inode_go_lock(struct gfs2_holder *gh) | 220 | static int inode_go_lock(struct gfs2_holder *gh) |
228 | { | 221 | { |
229 | struct gfs2_glock *gl = gh->gh_gl; | 222 | struct gfs2_glock *gl = gh->gh_gl; |
223 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
230 | struct gfs2_inode *ip = gl->gl_object; | 224 | struct gfs2_inode *ip = gl->gl_object; |
231 | int error = 0; | 225 | int error = 0; |
232 | 226 | ||
@@ -239,10 +233,16 @@ static int inode_go_lock(struct gfs2_holder *gh) | |||
239 | return error; | 233 | return error; |
240 | } | 234 | } |
241 | 235 | ||
242 | if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) && | 236 | if ((ip->i_diskflags & GFS2_DIF_TRUNC_IN_PROG) && |
243 | (gl->gl_state == LM_ST_EXCLUSIVE) && | 237 | (gl->gl_state == LM_ST_EXCLUSIVE) && |
244 | (gh->gh_state == LM_ST_EXCLUSIVE)) | 238 | (gh->gh_state == LM_ST_EXCLUSIVE)) { |
245 | error = gfs2_truncatei_resume(ip); | 239 | spin_lock(&sdp->sd_trunc_lock); |
240 | if (list_empty(&ip->i_trunc_list)) | ||
241 | list_add(&sdp->sd_trunc_list, &ip->i_trunc_list); | ||
242 | spin_unlock(&sdp->sd_trunc_lock); | ||
243 | wake_up(&sdp->sd_quota_wait); | ||
244 | return 1; | ||
245 | } | ||
246 | 246 | ||
247 | return error; | 247 | return error; |
248 | } | 248 | } |
@@ -260,10 +260,13 @@ static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) | |||
260 | const struct gfs2_inode *ip = gl->gl_object; | 260 | const struct gfs2_inode *ip = gl->gl_object; |
261 | if (ip == NULL) | 261 | if (ip == NULL) |
262 | return 0; | 262 | return 0; |
263 | gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%08lx\n", | 263 | gfs2_print_dbg(seq, " I: n:%llu/%llu t:%u f:0x%02lx d:0x%08x s:%llu/%llu\n", |
264 | (unsigned long long)ip->i_no_formal_ino, | 264 | (unsigned long long)ip->i_no_formal_ino, |
265 | (unsigned long long)ip->i_no_addr, | 265 | (unsigned long long)ip->i_no_addr, |
266 | IF2DT(ip->i_inode.i_mode), ip->i_flags); | 266 | IF2DT(ip->i_inode.i_mode), ip->i_flags, |
267 | (unsigned int)ip->i_diskflags, | ||
268 | (unsigned long long)ip->i_inode.i_size, | ||
269 | (unsigned long long)ip->i_disksize); | ||
267 | return 0; | 270 | return 0; |
268 | } | 271 | } |
269 | 272 | ||
@@ -274,7 +277,7 @@ static int inode_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) | |||
274 | * Returns: 1 if it's ok | 277 | * Returns: 1 if it's ok |
275 | */ | 278 | */ |
276 | 279 | ||
277 | static int rgrp_go_demote_ok(struct gfs2_glock *gl) | 280 | static int rgrp_go_demote_ok(const struct gfs2_glock *gl) |
278 | { | 281 | { |
279 | return !gl->gl_aspace->i_mapping->nrpages; | 282 | return !gl->gl_aspace->i_mapping->nrpages; |
280 | } | 283 | } |
@@ -318,7 +321,9 @@ static int rgrp_go_dump(struct seq_file *seq, const struct gfs2_glock *gl) | |||
318 | const struct gfs2_rgrpd *rgd = gl->gl_object; | 321 | const struct gfs2_rgrpd *rgd = gl->gl_object; |
319 | if (rgd == NULL) | 322 | if (rgd == NULL) |
320 | return 0; | 323 | return 0; |
321 | gfs2_print_dbg(seq, " R: n:%llu\n", (unsigned long long)rgd->rd_addr); | 324 | gfs2_print_dbg(seq, " R: n:%llu f:%02x b:%u/%u i:%u\n", |
325 | (unsigned long long)rgd->rd_addr, rgd->rd_flags, | ||
326 | rgd->rd_free, rgd->rd_free_clone, rgd->rd_dinodes); | ||
322 | return 0; | 327 | return 0; |
323 | } | 328 | } |
324 | 329 | ||
@@ -374,13 +379,25 @@ static int trans_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh) | |||
374 | } | 379 | } |
375 | 380 | ||
376 | /** | 381 | /** |
382 | * trans_go_demote_ok | ||
383 | * @gl: the glock | ||
384 | * | ||
385 | * Always returns 0 | ||
386 | */ | ||
387 | |||
388 | static int trans_go_demote_ok(const struct gfs2_glock *gl) | ||
389 | { | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | /** | ||
377 | * quota_go_demote_ok - Check to see if it's ok to unlock a quota glock | 394 | * quota_go_demote_ok - Check to see if it's ok to unlock a quota glock |
378 | * @gl: the glock | 395 | * @gl: the glock |
379 | * | 396 | * |
380 | * Returns: 1 if it's ok | 397 | * Returns: 1 if it's ok |
381 | */ | 398 | */ |
382 | 399 | ||
383 | static int quota_go_demote_ok(struct gfs2_glock *gl) | 400 | static int quota_go_demote_ok(const struct gfs2_glock *gl) |
384 | { | 401 | { |
385 | return !atomic_read(&gl->gl_lvb_count); | 402 | return !atomic_read(&gl->gl_lvb_count); |
386 | } | 403 | } |
@@ -414,6 +431,7 @@ const struct gfs2_glock_operations gfs2_rgrp_glops = { | |||
414 | const struct gfs2_glock_operations gfs2_trans_glops = { | 431 | const struct gfs2_glock_operations gfs2_trans_glops = { |
415 | .go_xmote_th = trans_go_sync, | 432 | .go_xmote_th = trans_go_sync, |
416 | .go_xmote_bh = trans_go_xmote_bh, | 433 | .go_xmote_bh = trans_go_xmote_bh, |
434 | .go_demote_ok = trans_go_demote_ok, | ||
417 | .go_type = LM_TYPE_NONDISK, | 435 | .go_type = LM_TYPE_NONDISK, |
418 | }; | 436 | }; |
419 | 437 | ||
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index f566ec1b4e8e..608849d00021 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -68,12 +68,6 @@ struct gfs2_bitmap { | |||
68 | u32 bi_len; | 68 | u32 bi_len; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | struct gfs2_rgrp_host { | ||
72 | u32 rg_free; | ||
73 | u32 rg_dinodes; | ||
74 | u64 rg_igeneration; | ||
75 | }; | ||
76 | |||
77 | struct gfs2_rgrpd { | 71 | struct gfs2_rgrpd { |
78 | struct list_head rd_list; /* Link with superblock */ | 72 | struct list_head rd_list; /* Link with superblock */ |
79 | struct list_head rd_list_mru; | 73 | struct list_head rd_list_mru; |
@@ -83,14 +77,16 @@ struct gfs2_rgrpd { | |||
83 | u32 rd_length; /* length of rgrp header in fs blocks */ | 77 | u32 rd_length; /* length of rgrp header in fs blocks */ |
84 | u32 rd_data; /* num of data blocks in rgrp */ | 78 | u32 rd_data; /* num of data blocks in rgrp */ |
85 | u32 rd_bitbytes; /* number of bytes in data bitmaps */ | 79 | u32 rd_bitbytes; /* number of bytes in data bitmaps */ |
86 | struct gfs2_rgrp_host rd_rg; | 80 | u32 rd_free; |
81 | u32 rd_free_clone; | ||
82 | u32 rd_dinodes; | ||
83 | u64 rd_igeneration; | ||
87 | struct gfs2_bitmap *rd_bits; | 84 | struct gfs2_bitmap *rd_bits; |
88 | unsigned int rd_bh_count; | ||
89 | struct mutex rd_mutex; | 85 | struct mutex rd_mutex; |
90 | u32 rd_free_clone; | ||
91 | struct gfs2_log_element rd_le; | 86 | struct gfs2_log_element rd_le; |
92 | u32 rd_last_alloc; | ||
93 | struct gfs2_sbd *rd_sbd; | 87 | struct gfs2_sbd *rd_sbd; |
88 | unsigned int rd_bh_count; | ||
89 | u32 rd_last_alloc; | ||
94 | unsigned char rd_flags; | 90 | unsigned char rd_flags; |
95 | #define GFS2_RDF_CHECK 0x01 /* Need to check for unlinked inodes */ | 91 | #define GFS2_RDF_CHECK 0x01 /* Need to check for unlinked inodes */ |
96 | #define GFS2_RDF_NOALLOC 0x02 /* rg prohibits allocation */ | 92 | #define GFS2_RDF_NOALLOC 0x02 /* rg prohibits allocation */ |
@@ -129,7 +125,7 @@ struct gfs2_glock_operations { | |||
129 | void (*go_xmote_th) (struct gfs2_glock *gl); | 125 | void (*go_xmote_th) (struct gfs2_glock *gl); |
130 | int (*go_xmote_bh) (struct gfs2_glock *gl, struct gfs2_holder *gh); | 126 | int (*go_xmote_bh) (struct gfs2_glock *gl, struct gfs2_holder *gh); |
131 | void (*go_inval) (struct gfs2_glock *gl, int flags); | 127 | void (*go_inval) (struct gfs2_glock *gl, int flags); |
132 | int (*go_demote_ok) (struct gfs2_glock *gl); | 128 | int (*go_demote_ok) (const struct gfs2_glock *gl); |
133 | int (*go_lock) (struct gfs2_holder *gh); | 129 | int (*go_lock) (struct gfs2_holder *gh); |
134 | void (*go_unlock) (struct gfs2_holder *gh); | 130 | void (*go_unlock) (struct gfs2_holder *gh); |
135 | int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); | 131 | int (*go_dump)(struct seq_file *seq, const struct gfs2_glock *gl); |
@@ -159,7 +155,6 @@ struct gfs2_holder { | |||
159 | 155 | ||
160 | enum { | 156 | enum { |
161 | GLF_LOCK = 1, | 157 | GLF_LOCK = 1, |
162 | GLF_STICKY = 2, | ||
163 | GLF_DEMOTE = 3, | 158 | GLF_DEMOTE = 3, |
164 | GLF_PENDING_DEMOTE = 4, | 159 | GLF_PENDING_DEMOTE = 4, |
165 | GLF_DEMOTE_IN_PROGRESS = 5, | 160 | GLF_DEMOTE_IN_PROGRESS = 5, |
@@ -194,7 +189,7 @@ struct gfs2_glock { | |||
194 | unsigned long gl_tchange; | 189 | unsigned long gl_tchange; |
195 | void *gl_object; | 190 | void *gl_object; |
196 | 191 | ||
197 | struct list_head gl_reclaim; | 192 | struct list_head gl_lru; |
198 | 193 | ||
199 | struct gfs2_sbd *gl_sbd; | 194 | struct gfs2_sbd *gl_sbd; |
200 | 195 | ||
@@ -233,29 +228,24 @@ enum { | |||
233 | GIF_USER = 4, /* user inode, not metadata addr space */ | 228 | GIF_USER = 4, /* user inode, not metadata addr space */ |
234 | }; | 229 | }; |
235 | 230 | ||
236 | struct gfs2_dinode_host { | ||
237 | u64 di_size; /* number of bytes in file */ | ||
238 | u64 di_generation; /* generation number for NFS */ | ||
239 | u32 di_flags; /* GFS2_DIF_... */ | ||
240 | /* These only apply to directories */ | ||
241 | u32 di_entries; /* The number of entries in the directory */ | ||
242 | u64 di_eattr; /* extended attribute block number */ | ||
243 | }; | ||
244 | 231 | ||
245 | struct gfs2_inode { | 232 | struct gfs2_inode { |
246 | struct inode i_inode; | 233 | struct inode i_inode; |
247 | u64 i_no_addr; | 234 | u64 i_no_addr; |
248 | u64 i_no_formal_ino; | 235 | u64 i_no_formal_ino; |
236 | u64 i_generation; | ||
237 | u64 i_eattr; | ||
238 | loff_t i_disksize; | ||
249 | unsigned long i_flags; /* GIF_... */ | 239 | unsigned long i_flags; /* GIF_... */ |
250 | |||
251 | struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ | ||
252 | |||
253 | struct gfs2_glock *i_gl; /* Move into i_gh? */ | 240 | struct gfs2_glock *i_gl; /* Move into i_gh? */ |
254 | struct gfs2_holder i_iopen_gh; | 241 | struct gfs2_holder i_iopen_gh; |
255 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ | 242 | struct gfs2_holder i_gh; /* for prepare/commit_write only */ |
256 | struct gfs2_alloc *i_alloc; | 243 | struct gfs2_alloc *i_alloc; |
257 | u64 i_goal; /* goal block for allocations */ | 244 | u64 i_goal; /* goal block for allocations */ |
258 | struct rw_semaphore i_rw_mutex; | 245 | struct rw_semaphore i_rw_mutex; |
246 | struct list_head i_trunc_list; | ||
247 | u32 i_entries; | ||
248 | u32 i_diskflags; | ||
259 | u8 i_height; | 249 | u8 i_height; |
260 | u8 i_depth; | 250 | u8 i_depth; |
261 | }; | 251 | }; |
@@ -406,13 +396,11 @@ struct gfs2_args { | |||
406 | struct gfs2_tune { | 396 | struct gfs2_tune { |
407 | spinlock_t gt_spin; | 397 | spinlock_t gt_spin; |
408 | 398 | ||
409 | unsigned int gt_demote_secs; /* Cache retention for unheld glock */ | ||
410 | unsigned int gt_incore_log_blocks; | 399 | unsigned int gt_incore_log_blocks; |
411 | unsigned int gt_log_flush_secs; | 400 | unsigned int gt_log_flush_secs; |
412 | 401 | ||
413 | unsigned int gt_recoverd_secs; | 402 | unsigned int gt_recoverd_secs; |
414 | unsigned int gt_logd_secs; | 403 | unsigned int gt_logd_secs; |
415 | unsigned int gt_quotad_secs; | ||
416 | 404 | ||
417 | unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ | 405 | unsigned int gt_quota_simul_sync; /* Max quotavals to sync at once */ |
418 | unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */ | 406 | unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */ |
@@ -488,10 +476,6 @@ struct gfs2_sbd { | |||
488 | /* Lock Stuff */ | 476 | /* Lock Stuff */ |
489 | 477 | ||
490 | struct lm_lockstruct sd_lockstruct; | 478 | struct lm_lockstruct sd_lockstruct; |
491 | struct list_head sd_reclaim_list; | ||
492 | spinlock_t sd_reclaim_lock; | ||
493 | wait_queue_head_t sd_reclaim_wq; | ||
494 | atomic_t sd_reclaim_count; | ||
495 | struct gfs2_holder sd_live_gh; | 479 | struct gfs2_holder sd_live_gh; |
496 | struct gfs2_glock *sd_rename_gl; | 480 | struct gfs2_glock *sd_rename_gl; |
497 | struct gfs2_glock *sd_trans_gl; | 481 | struct gfs2_glock *sd_trans_gl; |
@@ -519,7 +503,6 @@ struct gfs2_sbd { | |||
519 | spinlock_t sd_statfs_spin; | 503 | spinlock_t sd_statfs_spin; |
520 | struct gfs2_statfs_change_host sd_statfs_master; | 504 | struct gfs2_statfs_change_host sd_statfs_master; |
521 | struct gfs2_statfs_change_host sd_statfs_local; | 505 | struct gfs2_statfs_change_host sd_statfs_local; |
522 | unsigned long sd_statfs_sync_time; | ||
523 | 506 | ||
524 | /* Resource group stuff */ | 507 | /* Resource group stuff */ |
525 | 508 | ||
@@ -552,8 +535,6 @@ struct gfs2_sbd { | |||
552 | struct task_struct *sd_recoverd_process; | 535 | struct task_struct *sd_recoverd_process; |
553 | struct task_struct *sd_logd_process; | 536 | struct task_struct *sd_logd_process; |
554 | struct task_struct *sd_quotad_process; | 537 | struct task_struct *sd_quotad_process; |
555 | struct task_struct *sd_glockd_process[GFS2_GLOCKD_MAX]; | ||
556 | unsigned int sd_glockd_num; | ||
557 | 538 | ||
558 | /* Quota stuff */ | 539 | /* Quota stuff */ |
559 | 540 | ||
@@ -561,13 +542,15 @@ struct gfs2_sbd { | |||
561 | atomic_t sd_quota_count; | 542 | atomic_t sd_quota_count; |
562 | spinlock_t sd_quota_spin; | 543 | spinlock_t sd_quota_spin; |
563 | struct mutex sd_quota_mutex; | 544 | struct mutex sd_quota_mutex; |
545 | wait_queue_head_t sd_quota_wait; | ||
546 | struct list_head sd_trunc_list; | ||
547 | spinlock_t sd_trunc_lock; | ||
564 | 548 | ||
565 | unsigned int sd_quota_slots; | 549 | unsigned int sd_quota_slots; |
566 | unsigned int sd_quota_chunks; | 550 | unsigned int sd_quota_chunks; |
567 | unsigned char **sd_quota_bitmap; | 551 | unsigned char **sd_quota_bitmap; |
568 | 552 | ||
569 | u64 sd_quota_sync_gen; | 553 | u64 sd_quota_sync_gen; |
570 | unsigned long sd_quota_sync_time; | ||
571 | 554 | ||
572 | /* Log stuff */ | 555 | /* Log stuff */ |
573 | 556 | ||
@@ -624,10 +607,6 @@ struct gfs2_sbd { | |||
624 | struct mutex sd_freeze_lock; | 607 | struct mutex sd_freeze_lock; |
625 | unsigned int sd_freeze_count; | 608 | unsigned int sd_freeze_count; |
626 | 609 | ||
627 | /* Counters */ | ||
628 | |||
629 | atomic_t sd_reclaimed; | ||
630 | |||
631 | char sd_fsname[GFS2_FSNAME_LEN]; | 610 | char sd_fsname[GFS2_FSNAME_LEN]; |
632 | char sd_table_name[GFS2_FSNAME_LEN]; | 611 | char sd_table_name[GFS2_FSNAME_LEN]; |
633 | char sd_proto_name[GFS2_FSNAME_LEN]; | 612 | char sd_proto_name[GFS2_FSNAME_LEN]; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index d57616840e89..3b87c188da41 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include "log.h" | 32 | #include "log.h" |
33 | #include "meta_io.h" | 33 | #include "meta_io.h" |
34 | #include "ops_address.h" | 34 | #include "ops_address.h" |
35 | #include "ops_inode.h" | ||
36 | #include "quota.h" | 35 | #include "quota.h" |
37 | #include "rgrp.h" | 36 | #include "rgrp.h" |
38 | #include "trans.h" | 37 | #include "trans.h" |
@@ -248,7 +247,6 @@ fail: | |||
248 | 247 | ||
249 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | 248 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) |
250 | { | 249 | { |
251 | struct gfs2_dinode_host *di = &ip->i_di; | ||
252 | const struct gfs2_dinode *str = buf; | 250 | const struct gfs2_dinode *str = buf; |
253 | struct timespec atime; | 251 | struct timespec atime; |
254 | u16 height, depth; | 252 | u16 height, depth; |
@@ -274,8 +272,8 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
274 | * to do that. | 272 | * to do that. |
275 | */ | 273 | */ |
276 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | 274 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); |
277 | di->di_size = be64_to_cpu(str->di_size); | 275 | ip->i_disksize = be64_to_cpu(str->di_size); |
278 | i_size_write(&ip->i_inode, di->di_size); | 276 | i_size_write(&ip->i_inode, ip->i_disksize); |
279 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); | 277 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); |
280 | atime.tv_sec = be64_to_cpu(str->di_atime); | 278 | atime.tv_sec = be64_to_cpu(str->di_atime); |
281 | atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); | 279 | atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); |
@@ -287,9 +285,9 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
287 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); | 285 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); |
288 | 286 | ||
289 | ip->i_goal = be64_to_cpu(str->di_goal_meta); | 287 | ip->i_goal = be64_to_cpu(str->di_goal_meta); |
290 | di->di_generation = be64_to_cpu(str->di_generation); | 288 | ip->i_generation = be64_to_cpu(str->di_generation); |
291 | 289 | ||
292 | di->di_flags = be32_to_cpu(str->di_flags); | 290 | ip->i_diskflags = be32_to_cpu(str->di_flags); |
293 | gfs2_set_inode_flags(&ip->i_inode); | 291 | gfs2_set_inode_flags(&ip->i_inode); |
294 | height = be16_to_cpu(str->di_height); | 292 | height = be16_to_cpu(str->di_height); |
295 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) | 293 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) |
@@ -300,9 +298,9 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
300 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) | 298 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) |
301 | goto corrupt; | 299 | goto corrupt; |
302 | ip->i_depth = (u8)depth; | 300 | ip->i_depth = (u8)depth; |
303 | di->di_entries = be32_to_cpu(str->di_entries); | 301 | ip->i_entries = be32_to_cpu(str->di_entries); |
304 | 302 | ||
305 | di->di_eattr = be64_to_cpu(str->di_eattr); | 303 | ip->i_eattr = be64_to_cpu(str->di_eattr); |
306 | if (S_ISREG(ip->i_inode.i_mode)) | 304 | if (S_ISREG(ip->i_inode.i_mode)) |
307 | gfs2_set_aops(&ip->i_inode); | 305 | gfs2_set_aops(&ip->i_inode); |
308 | 306 | ||
@@ -388,7 +386,6 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
388 | gfs2_free_di(rgd, ip); | 386 | gfs2_free_di(rgd, ip); |
389 | 387 | ||
390 | gfs2_trans_end(sdp); | 388 | gfs2_trans_end(sdp); |
391 | clear_bit(GLF_STICKY, &ip->i_gl->gl_flags); | ||
392 | 389 | ||
393 | out_rg_gunlock: | 390 | out_rg_gunlock: |
394 | gfs2_glock_dq_uninit(&al->al_rgd_gh); | 391 | gfs2_glock_dq_uninit(&al->al_rgd_gh); |
@@ -690,7 +687,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
690 | return error; | 687 | return error; |
691 | } | 688 | } |
692 | 689 | ||
693 | if (dip->i_di.di_entries == (u32)-1) | 690 | if (dip->i_entries == (u32)-1) |
694 | return -EFBIG; | 691 | return -EFBIG; |
695 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) | 692 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) |
696 | return -EMLINK; | 693 | return -EMLINK; |
@@ -790,11 +787,11 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
790 | di->di_flags = 0; | 787 | di->di_flags = 0; |
791 | 788 | ||
792 | if (S_ISREG(mode)) { | 789 | if (S_ISREG(mode)) { |
793 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || | 790 | if ((dip->i_diskflags & GFS2_DIF_INHERIT_JDATA) || |
794 | gfs2_tune_get(sdp, gt_new_files_jdata)) | 791 | gfs2_tune_get(sdp, gt_new_files_jdata)) |
795 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); | 792 | di->di_flags |= cpu_to_be32(GFS2_DIF_JDATA); |
796 | } else if (S_ISDIR(mode)) { | 793 | } else if (S_ISDIR(mode)) { |
797 | di->di_flags |= cpu_to_be32(dip->i_di.di_flags & | 794 | di->di_flags |= cpu_to_be32(dip->i_diskflags & |
798 | GFS2_DIF_INHERIT_JDATA); | 795 | GFS2_DIF_INHERIT_JDATA); |
799 | } | 796 | } |
800 | 797 | ||
@@ -1068,7 +1065,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
1068 | struct qstr dotname; | 1065 | struct qstr dotname; |
1069 | int error; | 1066 | int error; |
1070 | 1067 | ||
1071 | if (ip->i_di.di_entries != 2) { | 1068 | if (ip->i_entries != 2) { |
1072 | if (gfs2_consist_inode(ip)) | 1069 | if (gfs2_consist_inode(ip)) |
1073 | gfs2_dinode_print(ip); | 1070 | gfs2_dinode_print(ip); |
1074 | return -EIO; | 1071 | return -EIO; |
@@ -1168,7 +1165,7 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | |||
1168 | return error; | 1165 | return error; |
1169 | } | 1166 | } |
1170 | 1167 | ||
1171 | if (!ip->i_di.di_size) { | 1168 | if (!ip->i_disksize) { |
1172 | gfs2_consist_inode(ip); | 1169 | gfs2_consist_inode(ip); |
1173 | error = -EIO; | 1170 | error = -EIO; |
1174 | goto out; | 1171 | goto out; |
@@ -1178,7 +1175,7 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | |||
1178 | if (error) | 1175 | if (error) |
1179 | goto out; | 1176 | goto out; |
1180 | 1177 | ||
1181 | x = ip->i_di.di_size + 1; | 1178 | x = ip->i_disksize + 1; |
1182 | if (x > *len) { | 1179 | if (x > *len) { |
1183 | *buf = kmalloc(x, GFP_NOFS); | 1180 | *buf = kmalloc(x, GFP_NOFS); |
1184 | if (!*buf) { | 1181 | if (!*buf) { |
@@ -1242,7 +1239,6 @@ int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
1242 | 1239 | ||
1243 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | 1240 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) |
1244 | { | 1241 | { |
1245 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
1246 | struct gfs2_dinode *str = buf; | 1242 | struct gfs2_dinode *str = buf; |
1247 | 1243 | ||
1248 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | 1244 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
@@ -1256,7 +1252,7 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | |||
1256 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); | 1252 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); |
1257 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | 1253 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); |
1258 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | 1254 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); |
1259 | str->di_size = cpu_to_be64(di->di_size); | 1255 | str->di_size = cpu_to_be64(ip->i_disksize); |
1260 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); | 1256 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); |
1261 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | 1257 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1262 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | 1258 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); |
@@ -1264,17 +1260,17 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | |||
1264 | 1260 | ||
1265 | str->di_goal_meta = cpu_to_be64(ip->i_goal); | 1261 | str->di_goal_meta = cpu_to_be64(ip->i_goal); |
1266 | str->di_goal_data = cpu_to_be64(ip->i_goal); | 1262 | str->di_goal_data = cpu_to_be64(ip->i_goal); |
1267 | str->di_generation = cpu_to_be64(di->di_generation); | 1263 | str->di_generation = cpu_to_be64(ip->i_generation); |
1268 | 1264 | ||
1269 | str->di_flags = cpu_to_be32(di->di_flags); | 1265 | str->di_flags = cpu_to_be32(ip->i_diskflags); |
1270 | str->di_height = cpu_to_be16(ip->i_height); | 1266 | str->di_height = cpu_to_be16(ip->i_height); |
1271 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | 1267 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && |
1272 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | 1268 | !(ip->i_diskflags & GFS2_DIF_EXHASH) ? |
1273 | GFS2_FORMAT_DE : 0); | 1269 | GFS2_FORMAT_DE : 0); |
1274 | str->di_depth = cpu_to_be16(ip->i_depth); | 1270 | str->di_depth = cpu_to_be16(ip->i_depth); |
1275 | str->di_entries = cpu_to_be32(di->di_entries); | 1271 | str->di_entries = cpu_to_be32(ip->i_entries); |
1276 | 1272 | ||
1277 | str->di_eattr = cpu_to_be64(di->di_eattr); | 1273 | str->di_eattr = cpu_to_be64(ip->i_eattr); |
1278 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); | 1274 | str->di_atime_nsec = cpu_to_be32(ip->i_inode.i_atime.tv_nsec); |
1279 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); | 1275 | str->di_mtime_nsec = cpu_to_be32(ip->i_inode.i_mtime.tv_nsec); |
1280 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); | 1276 | str->di_ctime_nsec = cpu_to_be32(ip->i_inode.i_ctime.tv_nsec); |
@@ -1282,22 +1278,21 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | |||
1282 | 1278 | ||
1283 | void gfs2_dinode_print(const struct gfs2_inode *ip) | 1279 | void gfs2_dinode_print(const struct gfs2_inode *ip) |
1284 | { | 1280 | { |
1285 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
1286 | |||
1287 | printk(KERN_INFO " no_formal_ino = %llu\n", | 1281 | printk(KERN_INFO " no_formal_ino = %llu\n", |
1288 | (unsigned long long)ip->i_no_formal_ino); | 1282 | (unsigned long long)ip->i_no_formal_ino); |
1289 | printk(KERN_INFO " no_addr = %llu\n", | 1283 | printk(KERN_INFO " no_addr = %llu\n", |
1290 | (unsigned long long)ip->i_no_addr); | 1284 | (unsigned long long)ip->i_no_addr); |
1291 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); | 1285 | printk(KERN_INFO " i_disksize = %llu\n", |
1286 | (unsigned long long)ip->i_disksize); | ||
1292 | printk(KERN_INFO " blocks = %llu\n", | 1287 | printk(KERN_INFO " blocks = %llu\n", |
1293 | (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode)); | 1288 | (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode)); |
1294 | printk(KERN_INFO " i_goal = %llu\n", | 1289 | printk(KERN_INFO " i_goal = %llu\n", |
1295 | (unsigned long long)ip->i_goal); | 1290 | (unsigned long long)ip->i_goal); |
1296 | printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); | 1291 | printk(KERN_INFO " i_diskflags = 0x%.8X\n", ip->i_diskflags); |
1297 | printk(KERN_INFO " i_height = %u\n", ip->i_height); | 1292 | printk(KERN_INFO " i_height = %u\n", ip->i_height); |
1298 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); | 1293 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); |
1299 | printk(KERN_INFO " di_entries = %u\n", di->di_entries); | 1294 | printk(KERN_INFO " i_entries = %u\n", ip->i_entries); |
1300 | printk(KERN_INFO " di_eattr = %llu\n", | 1295 | printk(KERN_INFO " i_eattr = %llu\n", |
1301 | (unsigned long long)di->di_eattr); | 1296 | (unsigned long long)ip->i_eattr); |
1302 | } | 1297 | } |
1303 | 1298 | ||
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index 2d43f69610a0..d5329364cdff 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #ifndef __INODE_DOT_H__ | 10 | #ifndef __INODE_DOT_H__ |
11 | #define __INODE_DOT_H__ | 11 | #define __INODE_DOT_H__ |
12 | 12 | ||
13 | #include <linux/fs.h> | ||
13 | #include "util.h" | 14 | #include "util.h" |
14 | 15 | ||
15 | static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) | 16 | static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) |
@@ -19,7 +20,7 @@ static inline int gfs2_is_stuffed(const struct gfs2_inode *ip) | |||
19 | 20 | ||
20 | static inline int gfs2_is_jdata(const struct gfs2_inode *ip) | 21 | static inline int gfs2_is_jdata(const struct gfs2_inode *ip) |
21 | { | 22 | { |
22 | return ip->i_di.di_flags & GFS2_DIF_JDATA; | 23 | return ip->i_diskflags & GFS2_DIF_JDATA; |
23 | } | 24 | } |
24 | 25 | ||
25 | static inline int gfs2_is_writeback(const struct gfs2_inode *ip) | 26 | static inline int gfs2_is_writeback(const struct gfs2_inode *ip) |
@@ -97,5 +98,15 @@ struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | |||
97 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); | 98 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf); |
98 | void gfs2_dinode_print(const struct gfs2_inode *ip); | 99 | void gfs2_dinode_print(const struct gfs2_inode *ip); |
99 | 100 | ||
101 | extern const struct inode_operations gfs2_file_iops; | ||
102 | extern const struct inode_operations gfs2_dir_iops; | ||
103 | extern const struct inode_operations gfs2_symlink_iops; | ||
104 | extern const struct file_operations gfs2_file_fops; | ||
105 | extern const struct file_operations gfs2_dir_fops; | ||
106 | extern const struct file_operations gfs2_file_fops_nolock; | ||
107 | extern const struct file_operations gfs2_dir_fops_nolock; | ||
108 | |||
109 | extern void gfs2_set_inode_flags(struct inode *inode); | ||
110 | |||
100 | #endif /* __INODE_DOT_H__ */ | 111 | #endif /* __INODE_DOT_H__ */ |
101 | 112 | ||
diff --git a/fs/gfs2/locking/dlm/mount.c b/fs/gfs2/locking/dlm/mount.c index 0c4cbe6c8285..1aa7eb6a0226 100644 --- a/fs/gfs2/locking/dlm/mount.c +++ b/fs/gfs2/locking/dlm/mount.c | |||
@@ -194,17 +194,25 @@ out: | |||
194 | static void gdlm_recovery_done(void *lockspace, unsigned int jid, | 194 | static void gdlm_recovery_done(void *lockspace, unsigned int jid, |
195 | unsigned int message) | 195 | unsigned int message) |
196 | { | 196 | { |
197 | char env_jid[20]; | ||
198 | char env_status[20]; | ||
199 | char *envp[] = { env_jid, env_status, NULL }; | ||
197 | struct gdlm_ls *ls = lockspace; | 200 | struct gdlm_ls *ls = lockspace; |
198 | ls->recover_jid_done = jid; | 201 | ls->recover_jid_done = jid; |
199 | ls->recover_jid_status = message; | 202 | ls->recover_jid_status = message; |
200 | kobject_uevent(&ls->kobj, KOBJ_CHANGE); | 203 | sprintf(env_jid, "JID=%d", jid); |
204 | sprintf(env_status, "RECOVERY=%s", | ||
205 | message == LM_RD_SUCCESS ? "Done" : "Failed"); | ||
206 | kobject_uevent_env(&ls->kobj, KOBJ_CHANGE, envp); | ||
201 | } | 207 | } |
202 | 208 | ||
203 | static void gdlm_others_may_mount(void *lockspace) | 209 | static void gdlm_others_may_mount(void *lockspace) |
204 | { | 210 | { |
211 | char *message = "FIRSTMOUNT=Done"; | ||
212 | char *envp[] = { message, NULL }; | ||
205 | struct gdlm_ls *ls = lockspace; | 213 | struct gdlm_ls *ls = lockspace; |
206 | ls->first_done = 1; | 214 | ls->first_done = 1; |
207 | kobject_uevent(&ls->kobj, KOBJ_CHANGE); | 215 | kobject_uevent_env(&ls->kobj, KOBJ_CHANGE, envp); |
208 | } | 216 | } |
209 | 217 | ||
210 | /* Userspace gets the offline uevent, blocks new gfs locks on | 218 | /* Userspace gets the offline uevent, blocks new gfs locks on |
diff --git a/fs/gfs2/locking/dlm/sysfs.c b/fs/gfs2/locking/dlm/sysfs.c index 4ec571c3d8a9..9b7edcf7bd49 100644 --- a/fs/gfs2/locking/dlm/sysfs.c +++ b/fs/gfs2/locking/dlm/sysfs.c | |||
@@ -195,9 +195,23 @@ void gdlm_kobject_release(struct gdlm_ls *ls) | |||
195 | kobject_put(&ls->kobj); | 195 | kobject_put(&ls->kobj); |
196 | } | 196 | } |
197 | 197 | ||
198 | static int gdlm_uevent(struct kset *kset, struct kobject *kobj, | ||
199 | struct kobj_uevent_env *env) | ||
200 | { | ||
201 | struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj); | ||
202 | add_uevent_var(env, "LOCKTABLE=%s:%s", ls->clustername, ls->fsname); | ||
203 | add_uevent_var(env, "LOCKPROTO=lock_dlm"); | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static struct kset_uevent_ops gdlm_uevent_ops = { | ||
208 | .uevent = gdlm_uevent, | ||
209 | }; | ||
210 | |||
211 | |||
198 | int gdlm_sysfs_init(void) | 212 | int gdlm_sysfs_init(void) |
199 | { | 213 | { |
200 | gdlm_kset = kset_create_and_add("lock_dlm", NULL, kernel_kobj); | 214 | gdlm_kset = kset_create_and_add("lock_dlm", &gdlm_uevent_ops, kernel_kobj); |
201 | if (!gdlm_kset) { | 215 | if (!gdlm_kset) { |
202 | printk(KERN_WARNING "%s: can not create kset\n", __func__); | 216 | printk(KERN_WARNING "%s: can not create kset\n", __func__); |
203 | return -ENOMEM; | 217 | return -ENOMEM; |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index bb2cc303ac29..7cacfde32194 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | #include "gfs2.h" | 20 | #include "gfs2.h" |
21 | #include "incore.h" | 21 | #include "incore.h" |
22 | #include "ops_fstype.h" | 22 | #include "super.h" |
23 | #include "sys.h" | 23 | #include "sys.h" |
24 | #include "util.h" | 24 | #include "util.h" |
25 | #include "glock.h" | 25 | #include "glock.h" |
@@ -30,6 +30,7 @@ static void gfs2_init_inode_once(void *foo) | |||
30 | 30 | ||
31 | inode_init_once(&ip->i_inode); | 31 | inode_init_once(&ip->i_inode); |
32 | init_rwsem(&ip->i_rw_mutex); | 32 | init_rwsem(&ip->i_rw_mutex); |
33 | INIT_LIST_HEAD(&ip->i_trunc_list); | ||
33 | ip->i_alloc = NULL; | 34 | ip->i_alloc = NULL; |
34 | } | 35 | } |
35 | 36 | ||
@@ -42,7 +43,7 @@ static void gfs2_init_glock_once(void *foo) | |||
42 | INIT_LIST_HEAD(&gl->gl_holders); | 43 | INIT_LIST_HEAD(&gl->gl_holders); |
43 | gl->gl_lvb = NULL; | 44 | gl->gl_lvb = NULL; |
44 | atomic_set(&gl->gl_lvb_count, 0); | 45 | atomic_set(&gl->gl_lvb_count, 0); |
45 | INIT_LIST_HEAD(&gl->gl_reclaim); | 46 | INIT_LIST_HEAD(&gl->gl_lru); |
46 | INIT_LIST_HEAD(&gl->gl_ail_list); | 47 | INIT_LIST_HEAD(&gl->gl_ail_list); |
47 | atomic_set(&gl->gl_ail_count, 0); | 48 | atomic_set(&gl->gl_ail_count, 0); |
48 | } | 49 | } |
@@ -93,6 +94,12 @@ static int __init init_gfs2_fs(void) | |||
93 | if (!gfs2_rgrpd_cachep) | 94 | if (!gfs2_rgrpd_cachep) |
94 | goto fail; | 95 | goto fail; |
95 | 96 | ||
97 | gfs2_quotad_cachep = kmem_cache_create("gfs2_quotad", | ||
98 | sizeof(struct gfs2_quota_data), | ||
99 | 0, 0, NULL); | ||
100 | if (!gfs2_quotad_cachep) | ||
101 | goto fail; | ||
102 | |||
96 | error = register_filesystem(&gfs2_fs_type); | 103 | error = register_filesystem(&gfs2_fs_type); |
97 | if (error) | 104 | if (error) |
98 | goto fail; | 105 | goto fail; |
@@ -112,6 +119,9 @@ fail_unregister: | |||
112 | fail: | 119 | fail: |
113 | gfs2_glock_exit(); | 120 | gfs2_glock_exit(); |
114 | 121 | ||
122 | if (gfs2_quotad_cachep) | ||
123 | kmem_cache_destroy(gfs2_quotad_cachep); | ||
124 | |||
115 | if (gfs2_rgrpd_cachep) | 125 | if (gfs2_rgrpd_cachep) |
116 | kmem_cache_destroy(gfs2_rgrpd_cachep); | 126 | kmem_cache_destroy(gfs2_rgrpd_cachep); |
117 | 127 | ||
@@ -140,6 +150,7 @@ static void __exit exit_gfs2_fs(void) | |||
140 | unregister_filesystem(&gfs2_fs_type); | 150 | unregister_filesystem(&gfs2_fs_type); |
141 | unregister_filesystem(&gfs2meta_fs_type); | 151 | unregister_filesystem(&gfs2meta_fs_type); |
142 | 152 | ||
153 | kmem_cache_destroy(gfs2_quotad_cachep); | ||
143 | kmem_cache_destroy(gfs2_rgrpd_cachep); | 154 | kmem_cache_destroy(gfs2_rgrpd_cachep); |
144 | kmem_cache_destroy(gfs2_bufdata_cachep); | 155 | kmem_cache_destroy(gfs2_bufdata_cachep); |
145 | kmem_cache_destroy(gfs2_inode_cachep); | 156 | kmem_cache_destroy(gfs2_inode_cachep); |
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c index f96eb90a2cfa..3cb0a44ba023 100644 --- a/fs/gfs2/mount.c +++ b/fs/gfs2/mount.c | |||
@@ -32,7 +32,6 @@ enum { | |||
32 | Opt_debug, | 32 | Opt_debug, |
33 | Opt_nodebug, | 33 | Opt_nodebug, |
34 | Opt_upgrade, | 34 | Opt_upgrade, |
35 | Opt_num_glockd, | ||
36 | Opt_acl, | 35 | Opt_acl, |
37 | Opt_noacl, | 36 | Opt_noacl, |
38 | Opt_quota_off, | 37 | Opt_quota_off, |
@@ -57,7 +56,6 @@ static const match_table_t tokens = { | |||
57 | {Opt_debug, "debug"}, | 56 | {Opt_debug, "debug"}, |
58 | {Opt_nodebug, "nodebug"}, | 57 | {Opt_nodebug, "nodebug"}, |
59 | {Opt_upgrade, "upgrade"}, | 58 | {Opt_upgrade, "upgrade"}, |
60 | {Opt_num_glockd, "num_glockd=%d"}, | ||
61 | {Opt_acl, "acl"}, | 59 | {Opt_acl, "acl"}, |
62 | {Opt_noacl, "noacl"}, | 60 | {Opt_noacl, "noacl"}, |
63 | {Opt_quota_off, "quota=off"}, | 61 | {Opt_quota_off, "quota=off"}, |
@@ -87,16 +85,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) | |||
87 | int error = 0; | 85 | int error = 0; |
88 | 86 | ||
89 | if (!remount) { | 87 | if (!remount) { |
90 | /* If someone preloaded options, use those instead */ | ||
91 | spin_lock(&gfs2_sys_margs_lock); | ||
92 | if (gfs2_sys_margs) { | ||
93 | data = gfs2_sys_margs; | ||
94 | gfs2_sys_margs = NULL; | ||
95 | } | ||
96 | spin_unlock(&gfs2_sys_margs_lock); | ||
97 | |||
98 | /* Set some defaults */ | 88 | /* Set some defaults */ |
99 | args->ar_num_glockd = GFS2_GLOCKD_DEFAULT; | ||
100 | args->ar_quota = GFS2_QUOTA_DEFAULT; | 89 | args->ar_quota = GFS2_QUOTA_DEFAULT; |
101 | args->ar_data = GFS2_DATA_DEFAULT; | 90 | args->ar_data = GFS2_DATA_DEFAULT; |
102 | } | 91 | } |
@@ -105,7 +94,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) | |||
105 | process them */ | 94 | process them */ |
106 | 95 | ||
107 | for (options = data; (o = strsep(&options, ",")); ) { | 96 | for (options = data; (o = strsep(&options, ",")); ) { |
108 | int token, option; | 97 | int token; |
109 | substring_t tmp[MAX_OPT_ARGS]; | 98 | substring_t tmp[MAX_OPT_ARGS]; |
110 | 99 | ||
111 | if (!*o) | 100 | if (!*o) |
@@ -196,22 +185,6 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, char *data_arg, int remount) | |||
196 | goto cant_remount; | 185 | goto cant_remount; |
197 | args->ar_upgrade = 1; | 186 | args->ar_upgrade = 1; |
198 | break; | 187 | break; |
199 | case Opt_num_glockd: | ||
200 | if ((error = match_int(&tmp[0], &option))) { | ||
201 | fs_info(sdp, "problem getting num_glockd\n"); | ||
202 | goto out_error; | ||
203 | } | ||
204 | |||
205 | if (remount && option != args->ar_num_glockd) | ||
206 | goto cant_remount; | ||
207 | if (!option || option > GFS2_GLOCKD_MAX) { | ||
208 | fs_info(sdp, "0 < num_glockd <= %u (not %u)\n", | ||
209 | GFS2_GLOCKD_MAX, option); | ||
210 | error = -EINVAL; | ||
211 | goto out_error; | ||
212 | } | ||
213 | args->ar_num_glockd = option; | ||
214 | break; | ||
215 | case Opt_acl: | 188 | case Opt_acl: |
216 | args->ar_posix_acl = 1; | 189 | args->ar_posix_acl = 1; |
217 | sdp->sd_vfs->s_flags |= MS_POSIXACL; | 190 | sdp->sd_vfs->s_flags |= MS_POSIXACL; |
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 15f710f2d4da..6e4ea36c6605 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -210,25 +210,23 @@ static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc | |||
210 | { | 210 | { |
211 | struct inode *inode = page->mapping->host; | 211 | struct inode *inode = page->mapping->host; |
212 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 212 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
213 | int error; | 213 | int ret; |
214 | int done_trans = 0; | 214 | int done_trans = 0; |
215 | 215 | ||
216 | error = gfs2_writepage_common(page, wbc); | ||
217 | if (error <= 0) | ||
218 | return error; | ||
219 | |||
220 | if (PageChecked(page)) { | 216 | if (PageChecked(page)) { |
221 | if (wbc->sync_mode != WB_SYNC_ALL) | 217 | if (wbc->sync_mode != WB_SYNC_ALL) |
222 | goto out_ignore; | 218 | goto out_ignore; |
223 | error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); | 219 | ret = gfs2_trans_begin(sdp, RES_DINODE + 1, 0); |
224 | if (error) | 220 | if (ret) |
225 | goto out_ignore; | 221 | goto out_ignore; |
226 | done_trans = 1; | 222 | done_trans = 1; |
227 | } | 223 | } |
228 | error = __gfs2_jdata_writepage(page, wbc); | 224 | ret = gfs2_writepage_common(page, wbc); |
225 | if (ret > 0) | ||
226 | ret = __gfs2_jdata_writepage(page, wbc); | ||
229 | if (done_trans) | 227 | if (done_trans) |
230 | gfs2_trans_end(sdp); | 228 | gfs2_trans_end(sdp); |
231 | return error; | 229 | return ret; |
232 | 230 | ||
233 | out_ignore: | 231 | out_ignore: |
234 | redirty_page_for_writepage(wbc, page); | 232 | redirty_page_for_writepage(wbc, page); |
@@ -453,8 +451,8 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | |||
453 | 451 | ||
454 | kaddr = kmap_atomic(page, KM_USER0); | 452 | kaddr = kmap_atomic(page, KM_USER0); |
455 | memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), | 453 | memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), |
456 | ip->i_di.di_size); | 454 | ip->i_disksize); |
457 | memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size); | 455 | memset(kaddr + ip->i_disksize, 0, PAGE_CACHE_SIZE - ip->i_disksize); |
458 | kunmap_atomic(kaddr, KM_USER0); | 456 | kunmap_atomic(kaddr, KM_USER0); |
459 | flush_dcache_page(page); | 457 | flush_dcache_page(page); |
460 | brelse(dibh); | 458 | brelse(dibh); |
@@ -627,7 +625,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
627 | { | 625 | { |
628 | struct gfs2_inode *ip = GFS2_I(mapping->host); | 626 | struct gfs2_inode *ip = GFS2_I(mapping->host); |
629 | struct gfs2_sbd *sdp = GFS2_SB(mapping->host); | 627 | struct gfs2_sbd *sdp = GFS2_SB(mapping->host); |
630 | unsigned int data_blocks, ind_blocks, rblocks; | 628 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
631 | int alloc_required; | 629 | int alloc_required; |
632 | int error = 0; | 630 | int error = 0; |
633 | struct gfs2_alloc *al; | 631 | struct gfs2_alloc *al; |
@@ -641,11 +639,13 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping, | |||
641 | if (unlikely(error)) | 639 | if (unlikely(error)) |
642 | goto out_uninit; | 640 | goto out_uninit; |
643 | 641 | ||
644 | gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); | ||
645 | error = gfs2_write_alloc_required(ip, pos, len, &alloc_required); | 642 | error = gfs2_write_alloc_required(ip, pos, len, &alloc_required); |
646 | if (error) | 643 | if (error) |
647 | goto out_unlock; | 644 | goto out_unlock; |
648 | 645 | ||
646 | if (alloc_required || gfs2_is_jdata(ip)) | ||
647 | gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks); | ||
648 | |||
649 | if (alloc_required) { | 649 | if (alloc_required) { |
650 | al = gfs2_alloc_get(ip); | 650 | al = gfs2_alloc_get(ip); |
651 | if (!al) { | 651 | if (!al) { |
@@ -782,7 +782,7 @@ static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh, | |||
782 | 782 | ||
783 | if (inode->i_size < to) { | 783 | if (inode->i_size < to) { |
784 | i_size_write(inode, to); | 784 | i_size_write(inode, to); |
785 | ip->i_di.di_size = inode->i_size; | 785 | ip->i_disksize = inode->i_size; |
786 | di->di_size = cpu_to_be64(inode->i_size); | 786 | di->di_size = cpu_to_be64(inode->i_size); |
787 | mark_inode_dirty(inode); | 787 | mark_inode_dirty(inode); |
788 | } | 788 | } |
@@ -847,9 +847,9 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, | |||
847 | 847 | ||
848 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); | 848 | ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); |
849 | 849 | ||
850 | if (likely(ret >= 0) && (inode->i_size > ip->i_di.di_size)) { | 850 | if (likely(ret >= 0) && (inode->i_size > ip->i_disksize)) { |
851 | di = (struct gfs2_dinode *)dibh->b_data; | 851 | di = (struct gfs2_dinode *)dibh->b_data; |
852 | ip->i_di.di_size = inode->i_size; | 852 | ip->i_disksize = inode->i_size; |
853 | di->di_size = cpu_to_be64(inode->i_size); | 853 | di->di_size = cpu_to_be64(inode->i_size); |
854 | mark_inode_dirty(inode); | 854 | mark_inode_dirty(inode); |
855 | } | 855 | } |
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c index 4a5e676b4420..c2ad36330ca3 100644 --- a/fs/gfs2/ops_dentry.c +++ b/fs/gfs2/ops_dentry.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include "incore.h" | 19 | #include "incore.h" |
20 | #include "dir.h" | 20 | #include "dir.h" |
21 | #include "glock.h" | 21 | #include "glock.h" |
22 | #include "ops_dentry.h" | 22 | #include "super.h" |
23 | #include "util.h" | 23 | #include "util.h" |
24 | #include "inode.h" | 24 | #include "inode.h" |
25 | 25 | ||
diff --git a/fs/gfs2/ops_dentry.h b/fs/gfs2/ops_dentry.h deleted file mode 100644 index 5caa3db4d3f5..000000000000 --- a/fs/gfs2/ops_dentry.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __OPS_DENTRY_DOT_H__ | ||
11 | #define __OPS_DENTRY_DOT_H__ | ||
12 | |||
13 | #include <linux/dcache.h> | ||
14 | |||
15 | extern struct dentry_operations gfs2_dops; | ||
16 | |||
17 | #endif /* __OPS_DENTRY_DOT_H__ */ | ||
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index bbb8c36403a9..7fdeb14ddd1a 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -22,8 +22,7 @@ | |||
22 | #include "glock.h" | 22 | #include "glock.h" |
23 | #include "glops.h" | 23 | #include "glops.h" |
24 | #include "inode.h" | 24 | #include "inode.h" |
25 | #include "ops_dentry.h" | 25 | #include "super.h" |
26 | #include "ops_fstype.h" | ||
27 | #include "rgrp.h" | 26 | #include "rgrp.h" |
28 | #include "util.h" | 27 | #include "util.h" |
29 | 28 | ||
@@ -214,7 +213,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, | |||
214 | } | 213 | } |
215 | 214 | ||
216 | error = -EIO; | 215 | error = -EIO; |
217 | if (GFS2_I(inode)->i_di.di_flags & GFS2_DIF_SYSTEM) { | 216 | if (GFS2_I(inode)->i_diskflags & GFS2_DIF_SYSTEM) { |
218 | iput(inode); | 217 | iput(inode); |
219 | goto fail; | 218 | goto fail; |
220 | } | 219 | } |
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 3a747f8e2188..289c5f54ba53 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include "util.h" | 39 | #include "util.h" |
40 | #include "eaops.h" | 40 | #include "eaops.h" |
41 | #include "ops_address.h" | 41 | #include "ops_address.h" |
42 | #include "ops_inode.h" | ||
43 | 42 | ||
44 | /** | 43 | /** |
45 | * gfs2_llseek - seek to a location in a file | 44 | * gfs2_llseek - seek to a location in a file |
@@ -158,8 +157,8 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
158 | if (error) | 157 | if (error) |
159 | return error; | 158 | return error; |
160 | 159 | ||
161 | fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_di.di_flags); | 160 | fsflags = fsflags_cvt(gfs2_to_fsflags, ip->i_diskflags); |
162 | if (!S_ISDIR(inode->i_mode) && ip->i_di.di_flags & GFS2_DIF_JDATA) | 161 | if (!S_ISDIR(inode->i_mode) && ip->i_diskflags & GFS2_DIF_JDATA) |
163 | fsflags |= FS_JOURNAL_DATA_FL; | 162 | fsflags |= FS_JOURNAL_DATA_FL; |
164 | if (put_user(fsflags, ptr)) | 163 | if (put_user(fsflags, ptr)) |
165 | error = -EFAULT; | 164 | error = -EFAULT; |
@@ -172,17 +171,16 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
172 | void gfs2_set_inode_flags(struct inode *inode) | 171 | void gfs2_set_inode_flags(struct inode *inode) |
173 | { | 172 | { |
174 | struct gfs2_inode *ip = GFS2_I(inode); | 173 | struct gfs2_inode *ip = GFS2_I(inode); |
175 | struct gfs2_dinode_host *di = &ip->i_di; | ||
176 | unsigned int flags = inode->i_flags; | 174 | unsigned int flags = inode->i_flags; |
177 | 175 | ||
178 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | 176 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); |
179 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | 177 | if (ip->i_diskflags & GFS2_DIF_IMMUTABLE) |
180 | flags |= S_IMMUTABLE; | 178 | flags |= S_IMMUTABLE; |
181 | if (di->di_flags & GFS2_DIF_APPENDONLY) | 179 | if (ip->i_diskflags & GFS2_DIF_APPENDONLY) |
182 | flags |= S_APPEND; | 180 | flags |= S_APPEND; |
183 | if (di->di_flags & GFS2_DIF_NOATIME) | 181 | if (ip->i_diskflags & GFS2_DIF_NOATIME) |
184 | flags |= S_NOATIME; | 182 | flags |= S_NOATIME; |
185 | if (di->di_flags & GFS2_DIF_SYNC) | 183 | if (ip->i_diskflags & GFS2_DIF_SYNC) |
186 | flags |= S_SYNC; | 184 | flags |= S_SYNC; |
187 | inode->i_flags = flags; | 185 | inode->i_flags = flags; |
188 | } | 186 | } |
@@ -221,7 +219,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
221 | if (error) | 219 | if (error) |
222 | goto out_drop_write; | 220 | goto out_drop_write; |
223 | 221 | ||
224 | flags = ip->i_di.di_flags; | 222 | flags = ip->i_diskflags; |
225 | new_flags = (flags & ~mask) | (reqflags & mask); | 223 | new_flags = (flags & ~mask) | (reqflags & mask); |
226 | if ((new_flags ^ flags) == 0) | 224 | if ((new_flags ^ flags) == 0) |
227 | goto out; | 225 | goto out; |
@@ -260,7 +258,7 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
260 | if (error) | 258 | if (error) |
261 | goto out_trans_end; | 259 | goto out_trans_end; |
262 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 260 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
263 | ip->i_di.di_flags = new_flags; | 261 | ip->i_diskflags = new_flags; |
264 | gfs2_dinode_out(ip, bh->b_data); | 262 | gfs2_dinode_out(ip, bh->b_data); |
265 | brelse(bh); | 263 | brelse(bh); |
266 | gfs2_set_inode_flags(inode); | 264 | gfs2_set_inode_flags(inode); |
@@ -357,7 +355,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
357 | goto out; | 355 | goto out; |
358 | 356 | ||
359 | set_bit(GIF_SW_PAGED, &ip->i_flags); | 357 | set_bit(GIF_SW_PAGED, &ip->i_flags); |
360 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); | ||
361 | ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); | 358 | ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required); |
362 | if (ret || !alloc_required) | 359 | if (ret || !alloc_required) |
363 | goto out_unlock; | 360 | goto out_unlock; |
@@ -369,6 +366,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
369 | ret = gfs2_quota_lock_check(ip); | 366 | ret = gfs2_quota_lock_check(ip); |
370 | if (ret) | 367 | if (ret) |
371 | goto out_alloc_put; | 368 | goto out_alloc_put; |
369 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); | ||
372 | al->al_requested = data_blocks + ind_blocks; | 370 | al->al_requested = data_blocks + ind_blocks; |
373 | ret = gfs2_inplace_reserve(ip); | 371 | ret = gfs2_inplace_reserve(ip); |
374 | if (ret) | 372 | if (ret) |
@@ -479,7 +477,7 @@ static int gfs2_open(struct inode *inode, struct file *file) | |||
479 | goto fail; | 477 | goto fail; |
480 | 478 | ||
481 | if (!(file->f_flags & O_LARGEFILE) && | 479 | if (!(file->f_flags & O_LARGEFILE) && |
482 | ip->i_di.di_size > MAX_NON_LFS) { | 480 | ip->i_disksize > MAX_NON_LFS) { |
483 | error = -EOVERFLOW; | 481 | error = -EOVERFLOW; |
484 | goto fail_gunlock; | 482 | goto fail_gunlock; |
485 | } | 483 | } |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index b117fcf2c4f5..f91eebdde581 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -22,20 +22,18 @@ | |||
22 | #include "gfs2.h" | 22 | #include "gfs2.h" |
23 | #include "incore.h" | 23 | #include "incore.h" |
24 | #include "bmap.h" | 24 | #include "bmap.h" |
25 | #include "daemon.h" | ||
26 | #include "glock.h" | 25 | #include "glock.h" |
27 | #include "glops.h" | 26 | #include "glops.h" |
28 | #include "inode.h" | 27 | #include "inode.h" |
29 | #include "mount.h" | 28 | #include "mount.h" |
30 | #include "ops_fstype.h" | ||
31 | #include "ops_dentry.h" | ||
32 | #include "ops_super.h" | ||
33 | #include "recovery.h" | 29 | #include "recovery.h" |
34 | #include "rgrp.h" | 30 | #include "rgrp.h" |
35 | #include "super.h" | 31 | #include "super.h" |
36 | #include "sys.h" | 32 | #include "sys.h" |
37 | #include "util.h" | 33 | #include "util.h" |
38 | #include "log.h" | 34 | #include "log.h" |
35 | #include "quota.h" | ||
36 | #include "dir.h" | ||
39 | 37 | ||
40 | #define DO 0 | 38 | #define DO 0 |
41 | #define UNDO 1 | 39 | #define UNDO 1 |
@@ -58,12 +56,10 @@ static void gfs2_tune_init(struct gfs2_tune *gt) | |||
58 | { | 56 | { |
59 | spin_lock_init(>->gt_spin); | 57 | spin_lock_init(>->gt_spin); |
60 | 58 | ||
61 | gt->gt_demote_secs = 300; | ||
62 | gt->gt_incore_log_blocks = 1024; | 59 | gt->gt_incore_log_blocks = 1024; |
63 | gt->gt_log_flush_secs = 60; | 60 | gt->gt_log_flush_secs = 60; |
64 | gt->gt_recoverd_secs = 60; | 61 | gt->gt_recoverd_secs = 60; |
65 | gt->gt_logd_secs = 1; | 62 | gt->gt_logd_secs = 1; |
66 | gt->gt_quotad_secs = 5; | ||
67 | gt->gt_quota_simul_sync = 64; | 63 | gt->gt_quota_simul_sync = 64; |
68 | gt->gt_quota_warn_period = 10; | 64 | gt->gt_quota_warn_period = 10; |
69 | gt->gt_quota_scale_num = 1; | 65 | gt->gt_quota_scale_num = 1; |
@@ -91,10 +87,6 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
91 | 87 | ||
92 | gfs2_tune_init(&sdp->sd_tune); | 88 | gfs2_tune_init(&sdp->sd_tune); |
93 | 89 | ||
94 | INIT_LIST_HEAD(&sdp->sd_reclaim_list); | ||
95 | spin_lock_init(&sdp->sd_reclaim_lock); | ||
96 | init_waitqueue_head(&sdp->sd_reclaim_wq); | ||
97 | |||
98 | mutex_init(&sdp->sd_inum_mutex); | 90 | mutex_init(&sdp->sd_inum_mutex); |
99 | spin_lock_init(&sdp->sd_statfs_spin); | 91 | spin_lock_init(&sdp->sd_statfs_spin); |
100 | 92 | ||
@@ -110,6 +102,9 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
110 | INIT_LIST_HEAD(&sdp->sd_quota_list); | 102 | INIT_LIST_HEAD(&sdp->sd_quota_list); |
111 | spin_lock_init(&sdp->sd_quota_spin); | 103 | spin_lock_init(&sdp->sd_quota_spin); |
112 | mutex_init(&sdp->sd_quota_mutex); | 104 | mutex_init(&sdp->sd_quota_mutex); |
105 | init_waitqueue_head(&sdp->sd_quota_wait); | ||
106 | INIT_LIST_HEAD(&sdp->sd_trunc_list); | ||
107 | spin_lock_init(&sdp->sd_trunc_lock); | ||
113 | 108 | ||
114 | spin_lock_init(&sdp->sd_log_lock); | 109 | spin_lock_init(&sdp->sd_log_lock); |
115 | 110 | ||
@@ -443,24 +438,11 @@ out: | |||
443 | static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh, | 438 | static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh, |
444 | int undo) | 439 | int undo) |
445 | { | 440 | { |
446 | struct task_struct *p; | ||
447 | int error = 0; | 441 | int error = 0; |
448 | 442 | ||
449 | if (undo) | 443 | if (undo) |
450 | goto fail_trans; | 444 | goto fail_trans; |
451 | 445 | ||
452 | for (sdp->sd_glockd_num = 0; | ||
453 | sdp->sd_glockd_num < sdp->sd_args.ar_num_glockd; | ||
454 | sdp->sd_glockd_num++) { | ||
455 | p = kthread_run(gfs2_glockd, sdp, "gfs2_glockd"); | ||
456 | error = IS_ERR(p); | ||
457 | if (error) { | ||
458 | fs_err(sdp, "can't start glockd thread: %d\n", error); | ||
459 | goto fail; | ||
460 | } | ||
461 | sdp->sd_glockd_process[sdp->sd_glockd_num] = p; | ||
462 | } | ||
463 | |||
464 | error = gfs2_glock_nq_num(sdp, | 446 | error = gfs2_glock_nq_num(sdp, |
465 | GFS2_MOUNT_LOCK, &gfs2_nondisk_glops, | 447 | GFS2_MOUNT_LOCK, &gfs2_nondisk_glops, |
466 | LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE, | 448 | LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE, |
@@ -493,7 +475,6 @@ static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh, | |||
493 | fs_err(sdp, "can't create transaction glock: %d\n", error); | 475 | fs_err(sdp, "can't create transaction glock: %d\n", error); |
494 | goto fail_rename; | 476 | goto fail_rename; |
495 | } | 477 | } |
496 | set_bit(GLF_STICKY, &sdp->sd_trans_gl->gl_flags); | ||
497 | 478 | ||
498 | return 0; | 479 | return 0; |
499 | 480 | ||
@@ -506,9 +487,6 @@ fail_live: | |||
506 | fail_mount: | 487 | fail_mount: |
507 | gfs2_glock_dq_uninit(mount_gh); | 488 | gfs2_glock_dq_uninit(mount_gh); |
508 | fail: | 489 | fail: |
509 | while (sdp->sd_glockd_num--) | ||
510 | kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]); | ||
511 | |||
512 | return error; | 490 | return error; |
513 | } | 491 | } |
514 | 492 | ||
@@ -620,7 +598,7 @@ static int map_journal_extents(struct gfs2_sbd *sdp) | |||
620 | 598 | ||
621 | prev_db = 0; | 599 | prev_db = 0; |
622 | 600 | ||
623 | for (lb = 0; lb < ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; lb++) { | 601 | for (lb = 0; lb < ip->i_disksize >> sdp->sd_sb.sb_bsize_shift; lb++) { |
624 | bh.b_state = 0; | 602 | bh.b_state = 0; |
625 | bh.b_blocknr = 0; | 603 | bh.b_blocknr = 0; |
626 | bh.b_size = 1 << ip->i_inode.i_blkbits; | 604 | bh.b_size = 1 << ip->i_inode.i_blkbits; |
@@ -661,6 +639,72 @@ static void gfs2_lm_others_may_mount(struct gfs2_sbd *sdp) | |||
661 | sdp->sd_lockstruct.ls_lockspace); | 639 | sdp->sd_lockstruct.ls_lockspace); |
662 | } | 640 | } |
663 | 641 | ||
642 | /** | ||
643 | * gfs2_jindex_hold - Grab a lock on the jindex | ||
644 | * @sdp: The GFS2 superblock | ||
645 | * @ji_gh: the holder for the jindex glock | ||
646 | * | ||
647 | * Returns: errno | ||
648 | */ | ||
649 | |||
650 | static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) | ||
651 | { | ||
652 | struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex); | ||
653 | struct qstr name; | ||
654 | char buf[20]; | ||
655 | struct gfs2_jdesc *jd; | ||
656 | int error; | ||
657 | |||
658 | name.name = buf; | ||
659 | |||
660 | mutex_lock(&sdp->sd_jindex_mutex); | ||
661 | |||
662 | for (;;) { | ||
663 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, ji_gh); | ||
664 | if (error) | ||
665 | break; | ||
666 | |||
667 | name.len = sprintf(buf, "journal%u", sdp->sd_journals); | ||
668 | name.hash = gfs2_disk_hash(name.name, name.len); | ||
669 | |||
670 | error = gfs2_dir_check(sdp->sd_jindex, &name, NULL); | ||
671 | if (error == -ENOENT) { | ||
672 | error = 0; | ||
673 | break; | ||
674 | } | ||
675 | |||
676 | gfs2_glock_dq_uninit(ji_gh); | ||
677 | |||
678 | if (error) | ||
679 | break; | ||
680 | |||
681 | error = -ENOMEM; | ||
682 | jd = kzalloc(sizeof(struct gfs2_jdesc), GFP_KERNEL); | ||
683 | if (!jd) | ||
684 | break; | ||
685 | |||
686 | INIT_LIST_HEAD(&jd->extent_list); | ||
687 | jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1); | ||
688 | if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { | ||
689 | if (!jd->jd_inode) | ||
690 | error = -ENOENT; | ||
691 | else | ||
692 | error = PTR_ERR(jd->jd_inode); | ||
693 | kfree(jd); | ||
694 | break; | ||
695 | } | ||
696 | |||
697 | spin_lock(&sdp->sd_jindex_spin); | ||
698 | jd->jd_jid = sdp->sd_journals++; | ||
699 | list_add_tail(&jd->jd_list, &sdp->sd_jindex_list); | ||
700 | spin_unlock(&sdp->sd_jindex_spin); | ||
701 | } | ||
702 | |||
703 | mutex_unlock(&sdp->sd_jindex_mutex); | ||
704 | |||
705 | return error; | ||
706 | } | ||
707 | |||
664 | static int init_journal(struct gfs2_sbd *sdp, int undo) | 708 | static int init_journal(struct gfs2_sbd *sdp, int undo) |
665 | { | 709 | { |
666 | struct inode *master = sdp->sd_master_dir->d_inode; | 710 | struct inode *master = sdp->sd_master_dir->d_inode; |
@@ -681,7 +725,6 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) | |||
681 | return PTR_ERR(sdp->sd_jindex); | 725 | return PTR_ERR(sdp->sd_jindex); |
682 | } | 726 | } |
683 | ip = GFS2_I(sdp->sd_jindex); | 727 | ip = GFS2_I(sdp->sd_jindex); |
684 | set_bit(GLF_STICKY, &ip->i_gl->gl_flags); | ||
685 | 728 | ||
686 | /* Load in the journal index special file */ | 729 | /* Load in the journal index special file */ |
687 | 730 | ||
@@ -832,7 +875,6 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo) | |||
832 | goto fail_statfs; | 875 | goto fail_statfs; |
833 | } | 876 | } |
834 | ip = GFS2_I(sdp->sd_rindex); | 877 | ip = GFS2_I(sdp->sd_rindex); |
835 | set_bit(GLF_STICKY, &ip->i_gl->gl_flags); | ||
836 | sdp->sd_rindex_uptodate = 0; | 878 | sdp->sd_rindex_uptodate = 0; |
837 | 879 | ||
838 | /* Read in the quota inode */ | 880 | /* Read in the quota inode */ |
@@ -973,9 +1015,6 @@ static int init_threads(struct gfs2_sbd *sdp, int undo) | |||
973 | } | 1015 | } |
974 | sdp->sd_logd_process = p; | 1016 | sdp->sd_logd_process = p; |
975 | 1017 | ||
976 | sdp->sd_statfs_sync_time = jiffies; | ||
977 | sdp->sd_quota_sync_time = jiffies; | ||
978 | |||
979 | p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad"); | 1018 | p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad"); |
980 | error = IS_ERR(p); | 1019 | error = IS_ERR(p); |
981 | if (error) { | 1020 | if (error) { |
@@ -1224,17 +1263,21 @@ static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, | |||
1224 | static void gfs2_kill_sb(struct super_block *sb) | 1263 | static void gfs2_kill_sb(struct super_block *sb) |
1225 | { | 1264 | { |
1226 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1265 | struct gfs2_sbd *sdp = sb->s_fs_info; |
1227 | if (sdp) { | 1266 | |
1228 | gfs2_meta_syncfs(sdp); | 1267 | if (sdp == NULL) { |
1229 | dput(sdp->sd_root_dir); | 1268 | kill_block_super(sb); |
1230 | dput(sdp->sd_master_dir); | 1269 | return; |
1231 | sdp->sd_root_dir = NULL; | ||
1232 | sdp->sd_master_dir = NULL; | ||
1233 | } | 1270 | } |
1271 | |||
1272 | gfs2_meta_syncfs(sdp); | ||
1273 | dput(sdp->sd_root_dir); | ||
1274 | dput(sdp->sd_master_dir); | ||
1275 | sdp->sd_root_dir = NULL; | ||
1276 | sdp->sd_master_dir = NULL; | ||
1234 | shrink_dcache_sb(sb); | 1277 | shrink_dcache_sb(sb); |
1235 | kill_block_super(sb); | 1278 | kill_block_super(sb); |
1236 | if (sdp) | 1279 | gfs2_delete_debugfs_file(sdp); |
1237 | gfs2_delete_debugfs_file(sdp); | 1280 | kfree(sdp); |
1238 | } | 1281 | } |
1239 | 1282 | ||
1240 | struct file_system_type gfs2_fs_type = { | 1283 | struct file_system_type gfs2_fs_type = { |
diff --git a/fs/gfs2/ops_fstype.h b/fs/gfs2/ops_fstype.h deleted file mode 100644 index da8490511836..000000000000 --- a/fs/gfs2/ops_fstype.h +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __OPS_FSTYPE_DOT_H__ | ||
11 | #define __OPS_FSTYPE_DOT_H__ | ||
12 | |||
13 | #include <linux/fs.h> | ||
14 | |||
15 | extern struct file_system_type gfs2_fs_type; | ||
16 | extern struct file_system_type gfs2meta_fs_type; | ||
17 | extern const struct export_operations gfs2_export_ops; | ||
18 | |||
19 | #endif /* __OPS_FSTYPE_DOT_H__ */ | ||
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index d232991b9046..49877546beb9 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/gfs2_ondisk.h> | 19 | #include <linux/gfs2_ondisk.h> |
20 | #include <linux/crc32.h> | 20 | #include <linux/crc32.h> |
21 | #include <linux/lm_interface.h> | 21 | #include <linux/lm_interface.h> |
22 | #include <linux/fiemap.h> | ||
22 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
23 | 24 | ||
24 | #include "gfs2.h" | 25 | #include "gfs2.h" |
@@ -31,12 +32,11 @@ | |||
31 | #include "glock.h" | 32 | #include "glock.h" |
32 | #include "inode.h" | 33 | #include "inode.h" |
33 | #include "meta_io.h" | 34 | #include "meta_io.h" |
34 | #include "ops_dentry.h" | ||
35 | #include "ops_inode.h" | ||
36 | #include "quota.h" | 35 | #include "quota.h" |
37 | #include "rgrp.h" | 36 | #include "rgrp.h" |
38 | #include "trans.h" | 37 | #include "trans.h" |
39 | #include "util.h" | 38 | #include "util.h" |
39 | #include "super.h" | ||
40 | 40 | ||
41 | /** | 41 | /** |
42 | * gfs2_create - Create a file | 42 | * gfs2_create - Create a file |
@@ -185,7 +185,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
185 | if (!dip->i_inode.i_nlink) | 185 | if (!dip->i_inode.i_nlink) |
186 | goto out_gunlock; | 186 | goto out_gunlock; |
187 | error = -EFBIG; | 187 | error = -EFBIG; |
188 | if (dip->i_di.di_entries == (u32)-1) | 188 | if (dip->i_entries == (u32)-1) |
189 | goto out_gunlock; | 189 | goto out_gunlock; |
190 | error = -EPERM; | 190 | error = -EPERM; |
191 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 191 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
@@ -371,7 +371,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
371 | 371 | ||
372 | ip = ghs[1].gh_gl->gl_object; | 372 | ip = ghs[1].gh_gl->gl_object; |
373 | 373 | ||
374 | ip->i_di.di_size = size; | 374 | ip->i_disksize = size; |
375 | 375 | ||
376 | error = gfs2_meta_inode_buffer(ip, &dibh); | 376 | error = gfs2_meta_inode_buffer(ip, &dibh); |
377 | 377 | ||
@@ -425,9 +425,9 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
425 | ip = ghs[1].gh_gl->gl_object; | 425 | ip = ghs[1].gh_gl->gl_object; |
426 | 426 | ||
427 | ip->i_inode.i_nlink = 2; | 427 | ip->i_inode.i_nlink = 2; |
428 | ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); | 428 | ip->i_disksize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); |
429 | ip->i_di.di_flags |= GFS2_DIF_JDATA; | 429 | ip->i_diskflags |= GFS2_DIF_JDATA; |
430 | ip->i_di.di_entries = 2; | 430 | ip->i_entries = 2; |
431 | 431 | ||
432 | error = gfs2_meta_inode_buffer(ip, &dibh); | 432 | error = gfs2_meta_inode_buffer(ip, &dibh); |
433 | 433 | ||
@@ -517,13 +517,13 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) | |||
517 | if (error) | 517 | if (error) |
518 | goto out_gunlock; | 518 | goto out_gunlock; |
519 | 519 | ||
520 | if (ip->i_di.di_entries < 2) { | 520 | if (ip->i_entries < 2) { |
521 | if (gfs2_consist_inode(ip)) | 521 | if (gfs2_consist_inode(ip)) |
522 | gfs2_dinode_print(ip); | 522 | gfs2_dinode_print(ip); |
523 | error = -EIO; | 523 | error = -EIO; |
524 | goto out_gunlock; | 524 | goto out_gunlock; |
525 | } | 525 | } |
526 | if (ip->i_di.di_entries > 2) { | 526 | if (ip->i_entries > 2) { |
527 | error = -ENOTEMPTY; | 527 | error = -ENOTEMPTY; |
528 | goto out_gunlock; | 528 | goto out_gunlock; |
529 | } | 529 | } |
@@ -726,13 +726,13 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
726 | goto out_gunlock; | 726 | goto out_gunlock; |
727 | 727 | ||
728 | if (S_ISDIR(nip->i_inode.i_mode)) { | 728 | if (S_ISDIR(nip->i_inode.i_mode)) { |
729 | if (nip->i_di.di_entries < 2) { | 729 | if (nip->i_entries < 2) { |
730 | if (gfs2_consist_inode(nip)) | 730 | if (gfs2_consist_inode(nip)) |
731 | gfs2_dinode_print(nip); | 731 | gfs2_dinode_print(nip); |
732 | error = -EIO; | 732 | error = -EIO; |
733 | goto out_gunlock; | 733 | goto out_gunlock; |
734 | } | 734 | } |
735 | if (nip->i_di.di_entries > 2) { | 735 | if (nip->i_entries > 2) { |
736 | error = -ENOTEMPTY; | 736 | error = -ENOTEMPTY; |
737 | goto out_gunlock; | 737 | goto out_gunlock; |
738 | } | 738 | } |
@@ -758,7 +758,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
758 | error = -EINVAL; | 758 | error = -EINVAL; |
759 | goto out_gunlock; | 759 | goto out_gunlock; |
760 | } | 760 | } |
761 | if (ndip->i_di.di_entries == (u32)-1) { | 761 | if (ndip->i_entries == (u32)-1) { |
762 | error = -EFBIG; | 762 | error = -EFBIG; |
763 | goto out_gunlock; | 763 | goto out_gunlock; |
764 | } | 764 | } |
@@ -990,7 +990,7 @@ static int setattr_size(struct inode *inode, struct iattr *attr) | |||
990 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 990 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
991 | int error; | 991 | int error; |
992 | 992 | ||
993 | if (attr->ia_size != ip->i_di.di_size) { | 993 | if (attr->ia_size != ip->i_disksize) { |
994 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 994 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
995 | if (error) | 995 | if (error) |
996 | return error; | 996 | return error; |
@@ -1001,8 +1001,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr) | |||
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | error = gfs2_truncatei(ip, attr->ia_size); | 1003 | error = gfs2_truncatei(ip, attr->ia_size); |
1004 | if (error && (inode->i_size != ip->i_di.di_size)) | 1004 | if (error && (inode->i_size != ip->i_disksize)) |
1005 | i_size_write(inode, ip->i_di.di_size); | 1005 | i_size_write(inode, ip->i_disksize); |
1006 | 1006 | ||
1007 | return error; | 1007 | return error; |
1008 | } | 1008 | } |
@@ -1212,6 +1212,48 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name) | |||
1212 | return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er); | 1212 | return gfs2_ea_remove(GFS2_I(dentry->d_inode), &er); |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | ||
1216 | u64 start, u64 len) | ||
1217 | { | ||
1218 | struct gfs2_inode *ip = GFS2_I(inode); | ||
1219 | struct gfs2_holder gh; | ||
1220 | int ret; | ||
1221 | |||
1222 | ret = fiemap_check_flags(fieinfo, FIEMAP_FLAG_SYNC); | ||
1223 | if (ret) | ||
1224 | return ret; | ||
1225 | |||
1226 | mutex_lock(&inode->i_mutex); | ||
1227 | |||
1228 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | ||
1229 | if (ret) | ||
1230 | goto out; | ||
1231 | |||
1232 | if (gfs2_is_stuffed(ip)) { | ||
1233 | u64 phys = ip->i_no_addr << inode->i_blkbits; | ||
1234 | u64 size = i_size_read(inode); | ||
1235 | u32 flags = FIEMAP_EXTENT_LAST|FIEMAP_EXTENT_NOT_ALIGNED| | ||
1236 | FIEMAP_EXTENT_DATA_INLINE; | ||
1237 | phys += sizeof(struct gfs2_dinode); | ||
1238 | phys += start; | ||
1239 | if (start + len > size) | ||
1240 | len = size - start; | ||
1241 | if (start < size) | ||
1242 | ret = fiemap_fill_next_extent(fieinfo, start, phys, | ||
1243 | len, flags); | ||
1244 | if (ret == 1) | ||
1245 | ret = 0; | ||
1246 | } else { | ||
1247 | ret = __generic_block_fiemap(inode, fieinfo, start, len, | ||
1248 | gfs2_block_map); | ||
1249 | } | ||
1250 | |||
1251 | gfs2_glock_dq_uninit(&gh); | ||
1252 | out: | ||
1253 | mutex_unlock(&inode->i_mutex); | ||
1254 | return ret; | ||
1255 | } | ||
1256 | |||
1215 | const struct inode_operations gfs2_file_iops = { | 1257 | const struct inode_operations gfs2_file_iops = { |
1216 | .permission = gfs2_permission, | 1258 | .permission = gfs2_permission, |
1217 | .setattr = gfs2_setattr, | 1259 | .setattr = gfs2_setattr, |
@@ -1220,6 +1262,7 @@ const struct inode_operations gfs2_file_iops = { | |||
1220 | .getxattr = gfs2_getxattr, | 1262 | .getxattr = gfs2_getxattr, |
1221 | .listxattr = gfs2_listxattr, | 1263 | .listxattr = gfs2_listxattr, |
1222 | .removexattr = gfs2_removexattr, | 1264 | .removexattr = gfs2_removexattr, |
1265 | .fiemap = gfs2_fiemap, | ||
1223 | }; | 1266 | }; |
1224 | 1267 | ||
1225 | const struct inode_operations gfs2_dir_iops = { | 1268 | const struct inode_operations gfs2_dir_iops = { |
@@ -1239,6 +1282,7 @@ const struct inode_operations gfs2_dir_iops = { | |||
1239 | .getxattr = gfs2_getxattr, | 1282 | .getxattr = gfs2_getxattr, |
1240 | .listxattr = gfs2_listxattr, | 1283 | .listxattr = gfs2_listxattr, |
1241 | .removexattr = gfs2_removexattr, | 1284 | .removexattr = gfs2_removexattr, |
1285 | .fiemap = gfs2_fiemap, | ||
1242 | }; | 1286 | }; |
1243 | 1287 | ||
1244 | const struct inode_operations gfs2_symlink_iops = { | 1288 | const struct inode_operations gfs2_symlink_iops = { |
@@ -1251,5 +1295,6 @@ const struct inode_operations gfs2_symlink_iops = { | |||
1251 | .getxattr = gfs2_getxattr, | 1295 | .getxattr = gfs2_getxattr, |
1252 | .listxattr = gfs2_listxattr, | 1296 | .listxattr = gfs2_listxattr, |
1253 | .removexattr = gfs2_removexattr, | 1297 | .removexattr = gfs2_removexattr, |
1298 | .fiemap = gfs2_fiemap, | ||
1254 | }; | 1299 | }; |
1255 | 1300 | ||
diff --git a/fs/gfs2/ops_inode.h b/fs/gfs2/ops_inode.h deleted file mode 100644 index 14b4b797622a..000000000000 --- a/fs/gfs2/ops_inode.h +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __OPS_INODE_DOT_H__ | ||
11 | #define __OPS_INODE_DOT_H__ | ||
12 | |||
13 | #include <linux/fs.h> | ||
14 | |||
15 | extern const struct inode_operations gfs2_file_iops; | ||
16 | extern const struct inode_operations gfs2_dir_iops; | ||
17 | extern const struct inode_operations gfs2_symlink_iops; | ||
18 | extern const struct file_operations gfs2_file_fops; | ||
19 | extern const struct file_operations gfs2_dir_fops; | ||
20 | extern const struct file_operations gfs2_file_fops_nolock; | ||
21 | extern const struct file_operations gfs2_dir_fops_nolock; | ||
22 | |||
23 | extern void gfs2_set_inode_flags(struct inode *inode); | ||
24 | |||
25 | #endif /* __OPS_INODE_DOT_H__ */ | ||
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index d5355d9b5926..777783deddcb 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "inode.h" | 28 | #include "inode.h" |
29 | #include "log.h" | 29 | #include "log.h" |
30 | #include "mount.h" | 30 | #include "mount.h" |
31 | #include "ops_super.h" | ||
32 | #include "quota.h" | 31 | #include "quota.h" |
33 | #include "recovery.h" | 32 | #include "recovery.h" |
34 | #include "rgrp.h" | 33 | #include "rgrp.h" |
@@ -143,8 +142,6 @@ static void gfs2_put_super(struct super_block *sb) | |||
143 | kthread_stop(sdp->sd_quotad_process); | 142 | kthread_stop(sdp->sd_quotad_process); |
144 | kthread_stop(sdp->sd_logd_process); | 143 | kthread_stop(sdp->sd_logd_process); |
145 | kthread_stop(sdp->sd_recoverd_process); | 144 | kthread_stop(sdp->sd_recoverd_process); |
146 | while (sdp->sd_glockd_num--) | ||
147 | kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]); | ||
148 | 145 | ||
149 | if (!(sb->s_flags & MS_RDONLY)) { | 146 | if (!(sb->s_flags & MS_RDONLY)) { |
150 | error = gfs2_make_fs_ro(sdp); | 147 | error = gfs2_make_fs_ro(sdp); |
@@ -185,7 +182,6 @@ static void gfs2_put_super(struct super_block *sb) | |||
185 | 182 | ||
186 | /* At this point, we're through participating in the lockspace */ | 183 | /* At this point, we're through participating in the lockspace */ |
187 | gfs2_sys_fs_del(sdp); | 184 | gfs2_sys_fs_del(sdp); |
188 | kfree(sdp); | ||
189 | } | 185 | } |
190 | 186 | ||
191 | /** | 187 | /** |
@@ -260,6 +256,137 @@ static void gfs2_unlockfs(struct super_block *sb) | |||
260 | } | 256 | } |
261 | 257 | ||
262 | /** | 258 | /** |
259 | * statfs_fill - fill in the sg for a given RG | ||
260 | * @rgd: the RG | ||
261 | * @sc: the sc structure | ||
262 | * | ||
263 | * Returns: 0 on success, -ESTALE if the LVB is invalid | ||
264 | */ | ||
265 | |||
266 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | ||
267 | struct gfs2_statfs_change_host *sc) | ||
268 | { | ||
269 | gfs2_rgrp_verify(rgd); | ||
270 | sc->sc_total += rgd->rd_data; | ||
271 | sc->sc_free += rgd->rd_free; | ||
272 | sc->sc_dinodes += rgd->rd_dinodes; | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * gfs2_statfs_slow - Stat a filesystem using asynchronous locking | ||
278 | * @sdp: the filesystem | ||
279 | * @sc: the sc info that will be returned | ||
280 | * | ||
281 | * Any error (other than a signal) will cause this routine to fall back | ||
282 | * to the synchronous version. | ||
283 | * | ||
284 | * FIXME: This really shouldn't busy wait like this. | ||
285 | * | ||
286 | * Returns: errno | ||
287 | */ | ||
288 | |||
289 | static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
290 | { | ||
291 | struct gfs2_holder ri_gh; | ||
292 | struct gfs2_rgrpd *rgd_next; | ||
293 | struct gfs2_holder *gha, *gh; | ||
294 | unsigned int slots = 64; | ||
295 | unsigned int x; | ||
296 | int done; | ||
297 | int error = 0, err; | ||
298 | |||
299 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); | ||
300 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | ||
301 | if (!gha) | ||
302 | return -ENOMEM; | ||
303 | |||
304 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
305 | if (error) | ||
306 | goto out; | ||
307 | |||
308 | rgd_next = gfs2_rgrpd_get_first(sdp); | ||
309 | |||
310 | for (;;) { | ||
311 | done = 1; | ||
312 | |||
313 | for (x = 0; x < slots; x++) { | ||
314 | gh = gha + x; | ||
315 | |||
316 | if (gh->gh_gl && gfs2_glock_poll(gh)) { | ||
317 | err = gfs2_glock_wait(gh); | ||
318 | if (err) { | ||
319 | gfs2_holder_uninit(gh); | ||
320 | error = err; | ||
321 | } else { | ||
322 | if (!error) | ||
323 | error = statfs_slow_fill( | ||
324 | gh->gh_gl->gl_object, sc); | ||
325 | gfs2_glock_dq_uninit(gh); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | if (gh->gh_gl) | ||
330 | done = 0; | ||
331 | else if (rgd_next && !error) { | ||
332 | error = gfs2_glock_nq_init(rgd_next->rd_gl, | ||
333 | LM_ST_SHARED, | ||
334 | GL_ASYNC, | ||
335 | gh); | ||
336 | rgd_next = gfs2_rgrpd_get_next(rgd_next); | ||
337 | done = 0; | ||
338 | } | ||
339 | |||
340 | if (signal_pending(current)) | ||
341 | error = -ERESTARTSYS; | ||
342 | } | ||
343 | |||
344 | if (done) | ||
345 | break; | ||
346 | |||
347 | yield(); | ||
348 | } | ||
349 | |||
350 | gfs2_glock_dq_uninit(&ri_gh); | ||
351 | |||
352 | out: | ||
353 | kfree(gha); | ||
354 | return error; | ||
355 | } | ||
356 | |||
357 | /** | ||
358 | * gfs2_statfs_i - Do a statfs | ||
359 | * @sdp: the filesystem | ||
360 | * @sg: the sg structure | ||
361 | * | ||
362 | * Returns: errno | ||
363 | */ | ||
364 | |||
365 | static int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
366 | { | ||
367 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
368 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | ||
369 | |||
370 | spin_lock(&sdp->sd_statfs_spin); | ||
371 | |||
372 | *sc = *m_sc; | ||
373 | sc->sc_total += l_sc->sc_total; | ||
374 | sc->sc_free += l_sc->sc_free; | ||
375 | sc->sc_dinodes += l_sc->sc_dinodes; | ||
376 | |||
377 | spin_unlock(&sdp->sd_statfs_spin); | ||
378 | |||
379 | if (sc->sc_free < 0) | ||
380 | sc->sc_free = 0; | ||
381 | if (sc->sc_free > sc->sc_total) | ||
382 | sc->sc_free = sc->sc_total; | ||
383 | if (sc->sc_dinodes < 0) | ||
384 | sc->sc_dinodes = 0; | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | /** | ||
263 | * gfs2_statfs - Gather and return stats about the filesystem | 390 | * gfs2_statfs - Gather and return stats about the filesystem |
264 | * @sb: The superblock | 391 | * @sb: The superblock |
265 | * @statfsbuf: The buffer | 392 | * @statfsbuf: The buffer |
@@ -370,7 +497,6 @@ static void gfs2_clear_inode(struct inode *inode) | |||
370 | */ | 497 | */ |
371 | if (test_bit(GIF_USER, &ip->i_flags)) { | 498 | if (test_bit(GIF_USER, &ip->i_flags)) { |
372 | ip->i_gl->gl_object = NULL; | 499 | ip->i_gl->gl_object = NULL; |
373 | gfs2_glock_schedule_for_reclaim(ip->i_gl); | ||
374 | gfs2_glock_put(ip->i_gl); | 500 | gfs2_glock_put(ip->i_gl); |
375 | ip->i_gl = NULL; | 501 | ip->i_gl = NULL; |
376 | if (ip->i_iopen_gh.gh_gl) { | 502 | if (ip->i_iopen_gh.gh_gl) { |
@@ -423,8 +549,6 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
423 | seq_printf(s, ",debug"); | 549 | seq_printf(s, ",debug"); |
424 | if (args->ar_upgrade) | 550 | if (args->ar_upgrade) |
425 | seq_printf(s, ",upgrade"); | 551 | seq_printf(s, ",upgrade"); |
426 | if (args->ar_num_glockd != GFS2_GLOCKD_DEFAULT) | ||
427 | seq_printf(s, ",num_glockd=%u", args->ar_num_glockd); | ||
428 | if (args->ar_posix_acl) | 552 | if (args->ar_posix_acl) |
429 | seq_printf(s, ",acl"); | 553 | seq_printf(s, ",acl"); |
430 | if (args->ar_quota != GFS2_QUOTA_DEFAULT) { | 554 | if (args->ar_quota != GFS2_QUOTA_DEFAULT) { |
@@ -494,16 +618,16 @@ static void gfs2_delete_inode(struct inode *inode) | |||
494 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); | 618 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); |
495 | error = gfs2_glock_nq(&ip->i_iopen_gh); | 619 | error = gfs2_glock_nq(&ip->i_iopen_gh); |
496 | if (error) | 620 | if (error) |
497 | goto out_uninit; | 621 | goto out_truncate; |
498 | 622 | ||
499 | if (S_ISDIR(inode->i_mode) && | 623 | if (S_ISDIR(inode->i_mode) && |
500 | (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { | 624 | (ip->i_diskflags & GFS2_DIF_EXHASH)) { |
501 | error = gfs2_dir_exhash_dealloc(ip); | 625 | error = gfs2_dir_exhash_dealloc(ip); |
502 | if (error) | 626 | if (error) |
503 | goto out_unlock; | 627 | goto out_unlock; |
504 | } | 628 | } |
505 | 629 | ||
506 | if (ip->i_di.di_eattr) { | 630 | if (ip->i_eattr) { |
507 | error = gfs2_ea_dealloc(ip); | 631 | error = gfs2_ea_dealloc(ip); |
508 | if (error) | 632 | if (error) |
509 | goto out_unlock; | 633 | goto out_unlock; |
@@ -519,6 +643,7 @@ static void gfs2_delete_inode(struct inode *inode) | |||
519 | if (error) | 643 | if (error) |
520 | goto out_unlock; | 644 | goto out_unlock; |
521 | 645 | ||
646 | out_truncate: | ||
522 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 647 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
523 | if (error) | 648 | if (error) |
524 | goto out_unlock; | 649 | goto out_unlock; |
@@ -527,8 +652,8 @@ static void gfs2_delete_inode(struct inode *inode) | |||
527 | gfs2_trans_end(sdp); | 652 | gfs2_trans_end(sdp); |
528 | 653 | ||
529 | out_unlock: | 654 | out_unlock: |
530 | gfs2_glock_dq(&ip->i_iopen_gh); | 655 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) |
531 | out_uninit: | 656 | gfs2_glock_dq(&ip->i_iopen_gh); |
532 | gfs2_holder_uninit(&ip->i_iopen_gh); | 657 | gfs2_holder_uninit(&ip->i_iopen_gh); |
533 | gfs2_glock_dq_uninit(&gh); | 658 | gfs2_glock_dq_uninit(&gh); |
534 | if (error && error != GLR_TRYFAILED) | 659 | if (error && error != GLR_TRYFAILED) |
diff --git a/fs/gfs2/ops_super.h b/fs/gfs2/ops_super.h deleted file mode 100644 index 442a274c6272..000000000000 --- a/fs/gfs2/ops_super.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
4 | * | ||
5 | * This copyrighted material is made available to anyone wishing to use, | ||
6 | * modify, copy, or redistribute it subject to the terms and conditions | ||
7 | * of the GNU General Public License version 2. | ||
8 | */ | ||
9 | |||
10 | #ifndef __OPS_SUPER_DOT_H__ | ||
11 | #define __OPS_SUPER_DOT_H__ | ||
12 | |||
13 | #include <linux/fs.h> | ||
14 | |||
15 | extern const struct super_operations gfs2_super_ops; | ||
16 | |||
17 | #endif /* __OPS_SUPER_DOT_H__ */ | ||
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 3e073f5144fa..b08d09696b3e 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -46,6 +46,8 @@ | |||
46 | #include <linux/bio.h> | 46 | #include <linux/bio.h> |
47 | #include <linux/gfs2_ondisk.h> | 47 | #include <linux/gfs2_ondisk.h> |
48 | #include <linux/lm_interface.h> | 48 | #include <linux/lm_interface.h> |
49 | #include <linux/kthread.h> | ||
50 | #include <linux/freezer.h> | ||
49 | 51 | ||
50 | #include "gfs2.h" | 52 | #include "gfs2.h" |
51 | #include "incore.h" | 53 | #include "incore.h" |
@@ -94,7 +96,7 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id, | |||
94 | struct gfs2_quota_data *qd; | 96 | struct gfs2_quota_data *qd; |
95 | int error; | 97 | int error; |
96 | 98 | ||
97 | qd = kzalloc(sizeof(struct gfs2_quota_data), GFP_NOFS); | 99 | qd = kmem_cache_zalloc(gfs2_quotad_cachep, GFP_NOFS); |
98 | if (!qd) | 100 | if (!qd) |
99 | return -ENOMEM; | 101 | return -ENOMEM; |
100 | 102 | ||
@@ -119,7 +121,7 @@ static int qd_alloc(struct gfs2_sbd *sdp, int user, u32 id, | |||
119 | return 0; | 121 | return 0; |
120 | 122 | ||
121 | fail: | 123 | fail: |
122 | kfree(qd); | 124 | kmem_cache_free(gfs2_quotad_cachep, qd); |
123 | return error; | 125 | return error; |
124 | } | 126 | } |
125 | 127 | ||
@@ -158,7 +160,7 @@ static int qd_get(struct gfs2_sbd *sdp, int user, u32 id, int create, | |||
158 | if (qd || !create) { | 160 | if (qd || !create) { |
159 | if (new_qd) { | 161 | if (new_qd) { |
160 | gfs2_lvb_unhold(new_qd->qd_gl); | 162 | gfs2_lvb_unhold(new_qd->qd_gl); |
161 | kfree(new_qd); | 163 | kmem_cache_free(gfs2_quotad_cachep, new_qd); |
162 | } | 164 | } |
163 | *qdp = qd; | 165 | *qdp = qd; |
164 | return 0; | 166 | return 0; |
@@ -1013,7 +1015,7 @@ void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | |||
1013 | 1015 | ||
1014 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change)) | 1016 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), change)) |
1015 | return; | 1017 | return; |
1016 | if (ip->i_di.di_flags & GFS2_DIF_SYSTEM) | 1018 | if (ip->i_diskflags & GFS2_DIF_SYSTEM) |
1017 | return; | 1019 | return; |
1018 | 1020 | ||
1019 | for (x = 0; x < al->al_qd_num; x++) { | 1021 | for (x = 0; x < al->al_qd_num; x++) { |
@@ -1100,15 +1102,15 @@ static void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void * | |||
1100 | int gfs2_quota_init(struct gfs2_sbd *sdp) | 1102 | int gfs2_quota_init(struct gfs2_sbd *sdp) |
1101 | { | 1103 | { |
1102 | struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); | 1104 | struct gfs2_inode *ip = GFS2_I(sdp->sd_qc_inode); |
1103 | unsigned int blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; | 1105 | unsigned int blocks = ip->i_disksize >> sdp->sd_sb.sb_bsize_shift; |
1104 | unsigned int x, slot = 0; | 1106 | unsigned int x, slot = 0; |
1105 | unsigned int found = 0; | 1107 | unsigned int found = 0; |
1106 | u64 dblock; | 1108 | u64 dblock; |
1107 | u32 extlen = 0; | 1109 | u32 extlen = 0; |
1108 | int error; | 1110 | int error; |
1109 | 1111 | ||
1110 | if (!ip->i_di.di_size || ip->i_di.di_size > (64 << 20) || | 1112 | if (!ip->i_disksize || ip->i_disksize > (64 << 20) || |
1111 | ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1)) { | 1113 | ip->i_disksize & (sdp->sd_sb.sb_bsize - 1)) { |
1112 | gfs2_consist_inode(ip); | 1114 | gfs2_consist_inode(ip); |
1113 | return -EIO; | 1115 | return -EIO; |
1114 | } | 1116 | } |
@@ -1195,7 +1197,7 @@ fail: | |||
1195 | return error; | 1197 | return error; |
1196 | } | 1198 | } |
1197 | 1199 | ||
1198 | void gfs2_quota_scan(struct gfs2_sbd *sdp) | 1200 | static void gfs2_quota_scan(struct gfs2_sbd *sdp) |
1199 | { | 1201 | { |
1200 | struct gfs2_quota_data *qd, *safe; | 1202 | struct gfs2_quota_data *qd, *safe; |
1201 | LIST_HEAD(dead); | 1203 | LIST_HEAD(dead); |
@@ -1222,7 +1224,7 @@ void gfs2_quota_scan(struct gfs2_sbd *sdp) | |||
1222 | gfs2_assert_warn(sdp, !qd->qd_bh_count); | 1224 | gfs2_assert_warn(sdp, !qd->qd_bh_count); |
1223 | 1225 | ||
1224 | gfs2_lvb_unhold(qd->qd_gl); | 1226 | gfs2_lvb_unhold(qd->qd_gl); |
1225 | kfree(qd); | 1227 | kmem_cache_free(gfs2_quotad_cachep, qd); |
1226 | } | 1228 | } |
1227 | } | 1229 | } |
1228 | 1230 | ||
@@ -1257,7 +1259,7 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp) | |||
1257 | gfs2_assert_warn(sdp, !qd->qd_bh_count); | 1259 | gfs2_assert_warn(sdp, !qd->qd_bh_count); |
1258 | 1260 | ||
1259 | gfs2_lvb_unhold(qd->qd_gl); | 1261 | gfs2_lvb_unhold(qd->qd_gl); |
1260 | kfree(qd); | 1262 | kmem_cache_free(gfs2_quotad_cachep, qd); |
1261 | 1263 | ||
1262 | spin_lock(&sdp->sd_quota_spin); | 1264 | spin_lock(&sdp->sd_quota_spin); |
1263 | } | 1265 | } |
@@ -1272,3 +1274,94 @@ void gfs2_quota_cleanup(struct gfs2_sbd *sdp) | |||
1272 | } | 1274 | } |
1273 | } | 1275 | } |
1274 | 1276 | ||
1277 | static void quotad_error(struct gfs2_sbd *sdp, const char *msg, int error) | ||
1278 | { | ||
1279 | if (error == 0 || error == -EROFS) | ||
1280 | return; | ||
1281 | if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) | ||
1282 | fs_err(sdp, "gfs2_quotad: %s error %d\n", msg, error); | ||
1283 | } | ||
1284 | |||
1285 | static void quotad_check_timeo(struct gfs2_sbd *sdp, const char *msg, | ||
1286 | int (*fxn)(struct gfs2_sbd *sdp), | ||
1287 | unsigned long t, unsigned long *timeo, | ||
1288 | unsigned int *new_timeo) | ||
1289 | { | ||
1290 | if (t >= *timeo) { | ||
1291 | int error = fxn(sdp); | ||
1292 | quotad_error(sdp, msg, error); | ||
1293 | *timeo = gfs2_tune_get_i(&sdp->sd_tune, new_timeo) * HZ; | ||
1294 | } else { | ||
1295 | *timeo -= t; | ||
1296 | } | ||
1297 | } | ||
1298 | |||
1299 | static void quotad_check_trunc_list(struct gfs2_sbd *sdp) | ||
1300 | { | ||
1301 | struct gfs2_inode *ip; | ||
1302 | |||
1303 | while(1) { | ||
1304 | ip = NULL; | ||
1305 | spin_lock(&sdp->sd_trunc_lock); | ||
1306 | if (!list_empty(&sdp->sd_trunc_list)) { | ||
1307 | ip = list_entry(sdp->sd_trunc_list.next, | ||
1308 | struct gfs2_inode, i_trunc_list); | ||
1309 | list_del_init(&ip->i_trunc_list); | ||
1310 | } | ||
1311 | spin_unlock(&sdp->sd_trunc_lock); | ||
1312 | if (ip == NULL) | ||
1313 | return; | ||
1314 | gfs2_glock_finish_truncate(ip); | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | /** | ||
1319 | * gfs2_quotad - Write cached quota changes into the quota file | ||
1320 | * @sdp: Pointer to GFS2 superblock | ||
1321 | * | ||
1322 | */ | ||
1323 | |||
1324 | int gfs2_quotad(void *data) | ||
1325 | { | ||
1326 | struct gfs2_sbd *sdp = data; | ||
1327 | struct gfs2_tune *tune = &sdp->sd_tune; | ||
1328 | unsigned long statfs_timeo = 0; | ||
1329 | unsigned long quotad_timeo = 0; | ||
1330 | unsigned long t = 0; | ||
1331 | DEFINE_WAIT(wait); | ||
1332 | int empty; | ||
1333 | |||
1334 | while (!kthread_should_stop()) { | ||
1335 | |||
1336 | /* Update the master statfs file */ | ||
1337 | quotad_check_timeo(sdp, "statfs", gfs2_statfs_sync, t, | ||
1338 | &statfs_timeo, &tune->gt_statfs_quantum); | ||
1339 | |||
1340 | /* Update quota file */ | ||
1341 | quotad_check_timeo(sdp, "sync", gfs2_quota_sync, t, | ||
1342 | "ad_timeo, &tune->gt_quota_quantum); | ||
1343 | |||
1344 | /* FIXME: This should be turned into a shrinker */ | ||
1345 | gfs2_quota_scan(sdp); | ||
1346 | |||
1347 | /* Check for & recover partially truncated inodes */ | ||
1348 | quotad_check_trunc_list(sdp); | ||
1349 | |||
1350 | if (freezing(current)) | ||
1351 | refrigerator(); | ||
1352 | t = min(quotad_timeo, statfs_timeo); | ||
1353 | |||
1354 | prepare_to_wait(&sdp->sd_quota_wait, &wait, TASK_UNINTERRUPTIBLE); | ||
1355 | spin_lock(&sdp->sd_trunc_lock); | ||
1356 | empty = list_empty(&sdp->sd_trunc_list); | ||
1357 | spin_unlock(&sdp->sd_trunc_lock); | ||
1358 | if (empty) | ||
1359 | t -= schedule_timeout(t); | ||
1360 | else | ||
1361 | t = 0; | ||
1362 | finish_wait(&sdp->sd_quota_wait, &wait); | ||
1363 | } | ||
1364 | |||
1365 | return 0; | ||
1366 | } | ||
1367 | |||
diff --git a/fs/gfs2/quota.h b/fs/gfs2/quota.h index 3b7f4b0e5dfe..cec9032be97d 100644 --- a/fs/gfs2/quota.h +++ b/fs/gfs2/quota.h | |||
@@ -15,22 +15,22 @@ struct gfs2_sbd; | |||
15 | 15 | ||
16 | #define NO_QUOTA_CHANGE ((u32)-1) | 16 | #define NO_QUOTA_CHANGE ((u32)-1) |
17 | 17 | ||
18 | int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid); | 18 | extern int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid); |
19 | void gfs2_quota_unhold(struct gfs2_inode *ip); | 19 | extern void gfs2_quota_unhold(struct gfs2_inode *ip); |
20 | 20 | ||
21 | int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid); | 21 | extern int gfs2_quota_lock(struct gfs2_inode *ip, u32 uid, u32 gid); |
22 | void gfs2_quota_unlock(struct gfs2_inode *ip); | 22 | extern void gfs2_quota_unlock(struct gfs2_inode *ip); |
23 | 23 | ||
24 | int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid); | 24 | extern int gfs2_quota_check(struct gfs2_inode *ip, u32 uid, u32 gid); |
25 | void gfs2_quota_change(struct gfs2_inode *ip, s64 change, | 25 | extern void gfs2_quota_change(struct gfs2_inode *ip, s64 change, |
26 | u32 uid, u32 gid); | 26 | u32 uid, u32 gid); |
27 | 27 | ||
28 | int gfs2_quota_sync(struct gfs2_sbd *sdp); | 28 | extern int gfs2_quota_sync(struct gfs2_sbd *sdp); |
29 | int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id); | 29 | extern int gfs2_quota_refresh(struct gfs2_sbd *sdp, int user, u32 id); |
30 | 30 | ||
31 | int gfs2_quota_init(struct gfs2_sbd *sdp); | 31 | extern int gfs2_quota_init(struct gfs2_sbd *sdp); |
32 | void gfs2_quota_scan(struct gfs2_sbd *sdp); | 32 | extern void gfs2_quota_cleanup(struct gfs2_sbd *sdp); |
33 | void gfs2_quota_cleanup(struct gfs2_sbd *sdp); | 33 | extern int gfs2_quotad(void *data); |
34 | 34 | ||
35 | static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) | 35 | static inline int gfs2_quota_lock_check(struct gfs2_inode *ip) |
36 | { | 36 | { |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index d5e91f4f6a0b..efd09c3d2b26 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/gfs2_ondisk.h> | 14 | #include <linux/gfs2_ondisk.h> |
15 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
16 | #include <linux/lm_interface.h> | 16 | #include <linux/lm_interface.h> |
17 | #include <linux/kthread.h> | ||
18 | #include <linux/freezer.h> | ||
17 | 19 | ||
18 | #include "gfs2.h" | 20 | #include "gfs2.h" |
19 | #include "incore.h" | 21 | #include "incore.h" |
@@ -583,13 +585,35 @@ fail: | |||
583 | return error; | 585 | return error; |
584 | } | 586 | } |
585 | 587 | ||
588 | static struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp) | ||
589 | { | ||
590 | struct gfs2_jdesc *jd; | ||
591 | int found = 0; | ||
592 | |||
593 | spin_lock(&sdp->sd_jindex_spin); | ||
594 | |||
595 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
596 | if (jd->jd_dirty) { | ||
597 | jd->jd_dirty = 0; | ||
598 | found = 1; | ||
599 | break; | ||
600 | } | ||
601 | } | ||
602 | spin_unlock(&sdp->sd_jindex_spin); | ||
603 | |||
604 | if (!found) | ||
605 | jd = NULL; | ||
606 | |||
607 | return jd; | ||
608 | } | ||
609 | |||
586 | /** | 610 | /** |
587 | * gfs2_check_journals - Recover any dirty journals | 611 | * gfs2_check_journals - Recover any dirty journals |
588 | * @sdp: the filesystem | 612 | * @sdp: the filesystem |
589 | * | 613 | * |
590 | */ | 614 | */ |
591 | 615 | ||
592 | void gfs2_check_journals(struct gfs2_sbd *sdp) | 616 | static void gfs2_check_journals(struct gfs2_sbd *sdp) |
593 | { | 617 | { |
594 | struct gfs2_jdesc *jd; | 618 | struct gfs2_jdesc *jd; |
595 | 619 | ||
@@ -603,3 +627,25 @@ void gfs2_check_journals(struct gfs2_sbd *sdp) | |||
603 | } | 627 | } |
604 | } | 628 | } |
605 | 629 | ||
630 | /** | ||
631 | * gfs2_recoverd - Recover dead machine's journals | ||
632 | * @sdp: Pointer to GFS2 superblock | ||
633 | * | ||
634 | */ | ||
635 | |||
636 | int gfs2_recoverd(void *data) | ||
637 | { | ||
638 | struct gfs2_sbd *sdp = data; | ||
639 | unsigned long t; | ||
640 | |||
641 | while (!kthread_should_stop()) { | ||
642 | gfs2_check_journals(sdp); | ||
643 | t = gfs2_tune_get(sdp, gt_recoverd_secs) * HZ; | ||
644 | if (freezing(current)) | ||
645 | refrigerator(); | ||
646 | schedule_timeout_interruptible(t); | ||
647 | } | ||
648 | |||
649 | return 0; | ||
650 | } | ||
651 | |||
diff --git a/fs/gfs2/recovery.h b/fs/gfs2/recovery.h index f7235e61c723..a8218ea15b57 100644 --- a/fs/gfs2/recovery.h +++ b/fs/gfs2/recovery.h | |||
@@ -18,17 +18,17 @@ static inline void gfs2_replay_incr_blk(struct gfs2_sbd *sdp, unsigned int *blk) | |||
18 | *blk = 0; | 18 | *blk = 0; |
19 | } | 19 | } |
20 | 20 | ||
21 | int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk, | 21 | extern int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk, |
22 | struct buffer_head **bh); | 22 | struct buffer_head **bh); |
23 | 23 | ||
24 | int gfs2_revoke_add(struct gfs2_sbd *sdp, u64 blkno, unsigned int where); | 24 | extern int gfs2_revoke_add(struct gfs2_sbd *sdp, u64 blkno, unsigned int where); |
25 | int gfs2_revoke_check(struct gfs2_sbd *sdp, u64 blkno, unsigned int where); | 25 | extern int gfs2_revoke_check(struct gfs2_sbd *sdp, u64 blkno, unsigned int where); |
26 | void gfs2_revoke_clean(struct gfs2_sbd *sdp); | 26 | extern void gfs2_revoke_clean(struct gfs2_sbd *sdp); |
27 | 27 | ||
28 | int gfs2_find_jhead(struct gfs2_jdesc *jd, | 28 | extern int gfs2_find_jhead(struct gfs2_jdesc *jd, |
29 | struct gfs2_log_header_host *head); | 29 | struct gfs2_log_header_host *head); |
30 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); | 30 | extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); |
31 | void gfs2_check_journals(struct gfs2_sbd *sdp); | 31 | extern int gfs2_recoverd(void *data); |
32 | 32 | ||
33 | #endif /* __RECOVERY_DOT_H__ */ | 33 | #endif /* __RECOVERY_DOT_H__ */ |
34 | 34 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 2d90fb253505..8b01c635d925 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -269,16 +269,14 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | |||
269 | bi->bi_len, x); | 269 | bi->bi_len, x); |
270 | } | 270 | } |
271 | 271 | ||
272 | if (count[0] != rgd->rd_rg.rg_free) { | 272 | if (count[0] != rgd->rd_free) { |
273 | if (gfs2_consist_rgrpd(rgd)) | 273 | if (gfs2_consist_rgrpd(rgd)) |
274 | fs_err(sdp, "free data mismatch: %u != %u\n", | 274 | fs_err(sdp, "free data mismatch: %u != %u\n", |
275 | count[0], rgd->rd_rg.rg_free); | 275 | count[0], rgd->rd_free); |
276 | return; | 276 | return; |
277 | } | 277 | } |
278 | 278 | ||
279 | tmp = rgd->rd_data - | 279 | tmp = rgd->rd_data - rgd->rd_free - rgd->rd_dinodes; |
280 | rgd->rd_rg.rg_free - | ||
281 | rgd->rd_rg.rg_dinodes; | ||
282 | if (count[1] + count[2] != tmp) { | 280 | if (count[1] + count[2] != tmp) { |
283 | if (gfs2_consist_rgrpd(rgd)) | 281 | if (gfs2_consist_rgrpd(rgd)) |
284 | fs_err(sdp, "used data mismatch: %u != %u\n", | 282 | fs_err(sdp, "used data mismatch: %u != %u\n", |
@@ -286,10 +284,10 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | |||
286 | return; | 284 | return; |
287 | } | 285 | } |
288 | 286 | ||
289 | if (count[3] != rgd->rd_rg.rg_dinodes) { | 287 | if (count[3] != rgd->rd_dinodes) { |
290 | if (gfs2_consist_rgrpd(rgd)) | 288 | if (gfs2_consist_rgrpd(rgd)) |
291 | fs_err(sdp, "used metadata mismatch: %u != %u\n", | 289 | fs_err(sdp, "used metadata mismatch: %u != %u\n", |
292 | count[3], rgd->rd_rg.rg_dinodes); | 290 | count[3], rgd->rd_dinodes); |
293 | return; | 291 | return; |
294 | } | 292 | } |
295 | 293 | ||
@@ -501,7 +499,7 @@ u64 gfs2_ri_total(struct gfs2_sbd *sdp) | |||
501 | for (rgrps = 0;; rgrps++) { | 499 | for (rgrps = 0;; rgrps++) { |
502 | loff_t pos = rgrps * sizeof(struct gfs2_rindex); | 500 | loff_t pos = rgrps * sizeof(struct gfs2_rindex); |
503 | 501 | ||
504 | if (pos + sizeof(struct gfs2_rindex) >= ip->i_di.di_size) | 502 | if (pos + sizeof(struct gfs2_rindex) >= ip->i_disksize) |
505 | break; | 503 | break; |
506 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, | 504 | error = gfs2_internal_read(ip, &ra_state, buf, &pos, |
507 | sizeof(struct gfs2_rindex)); | 505 | sizeof(struct gfs2_rindex)); |
@@ -590,7 +588,7 @@ static int gfs2_ri_update(struct gfs2_inode *ip) | |||
590 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 588 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
591 | struct inode *inode = &ip->i_inode; | 589 | struct inode *inode = &ip->i_inode; |
592 | struct file_ra_state ra_state; | 590 | struct file_ra_state ra_state; |
593 | u64 rgrp_count = ip->i_di.di_size; | 591 | u64 rgrp_count = ip->i_disksize; |
594 | int error; | 592 | int error; |
595 | 593 | ||
596 | if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) { | 594 | if (do_div(rgrp_count, sizeof(struct gfs2_rindex))) { |
@@ -634,7 +632,7 @@ static int gfs2_ri_update_special(struct gfs2_inode *ip) | |||
634 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { | 632 | for (sdp->sd_rgrps = 0;; sdp->sd_rgrps++) { |
635 | /* Ignore partials */ | 633 | /* Ignore partials */ |
636 | if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) > | 634 | if ((sdp->sd_rgrps + 1) * sizeof(struct gfs2_rindex) > |
637 | ip->i_di.di_size) | 635 | ip->i_disksize) |
638 | break; | 636 | break; |
639 | error = read_rindex_entry(ip, &ra_state); | 637 | error = read_rindex_entry(ip, &ra_state); |
640 | if (error) { | 638 | if (error) { |
@@ -692,7 +690,6 @@ int gfs2_rindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ri_gh) | |||
692 | static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf) | 690 | static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf) |
693 | { | 691 | { |
694 | const struct gfs2_rgrp *str = buf; | 692 | const struct gfs2_rgrp *str = buf; |
695 | struct gfs2_rgrp_host *rg = &rgd->rd_rg; | ||
696 | u32 rg_flags; | 693 | u32 rg_flags; |
697 | 694 | ||
698 | rg_flags = be32_to_cpu(str->rg_flags); | 695 | rg_flags = be32_to_cpu(str->rg_flags); |
@@ -700,24 +697,23 @@ static void gfs2_rgrp_in(struct gfs2_rgrpd *rgd, const void *buf) | |||
700 | rgd->rd_flags |= GFS2_RDF_NOALLOC; | 697 | rgd->rd_flags |= GFS2_RDF_NOALLOC; |
701 | else | 698 | else |
702 | rgd->rd_flags &= ~GFS2_RDF_NOALLOC; | 699 | rgd->rd_flags &= ~GFS2_RDF_NOALLOC; |
703 | rg->rg_free = be32_to_cpu(str->rg_free); | 700 | rgd->rd_free = be32_to_cpu(str->rg_free); |
704 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); | 701 | rgd->rd_dinodes = be32_to_cpu(str->rg_dinodes); |
705 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); | 702 | rgd->rd_igeneration = be64_to_cpu(str->rg_igeneration); |
706 | } | 703 | } |
707 | 704 | ||
708 | static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) | 705 | static void gfs2_rgrp_out(struct gfs2_rgrpd *rgd, void *buf) |
709 | { | 706 | { |
710 | struct gfs2_rgrp *str = buf; | 707 | struct gfs2_rgrp *str = buf; |
711 | struct gfs2_rgrp_host *rg = &rgd->rd_rg; | ||
712 | u32 rg_flags = 0; | 708 | u32 rg_flags = 0; |
713 | 709 | ||
714 | if (rgd->rd_flags & GFS2_RDF_NOALLOC) | 710 | if (rgd->rd_flags & GFS2_RDF_NOALLOC) |
715 | rg_flags |= GFS2_RGF_NOALLOC; | 711 | rg_flags |= GFS2_RGF_NOALLOC; |
716 | str->rg_flags = cpu_to_be32(rg_flags); | 712 | str->rg_flags = cpu_to_be32(rg_flags); |
717 | str->rg_free = cpu_to_be32(rg->rg_free); | 713 | str->rg_free = cpu_to_be32(rgd->rd_free); |
718 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); | 714 | str->rg_dinodes = cpu_to_be32(rgd->rd_dinodes); |
719 | str->__pad = cpu_to_be32(0); | 715 | str->__pad = cpu_to_be32(0); |
720 | str->rg_igeneration = cpu_to_be64(rg->rg_igeneration); | 716 | str->rg_igeneration = cpu_to_be64(rgd->rd_igeneration); |
721 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); | 717 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); |
722 | } | 718 | } |
723 | 719 | ||
@@ -776,7 +772,7 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
776 | } | 772 | } |
777 | 773 | ||
778 | spin_lock(&sdp->sd_rindex_spin); | 774 | spin_lock(&sdp->sd_rindex_spin); |
779 | rgd->rd_free_clone = rgd->rd_rg.rg_free; | 775 | rgd->rd_free_clone = rgd->rd_free; |
780 | rgd->rd_bh_count++; | 776 | rgd->rd_bh_count++; |
781 | spin_unlock(&sdp->sd_rindex_spin); | 777 | spin_unlock(&sdp->sd_rindex_spin); |
782 | 778 | ||
@@ -850,7 +846,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) | |||
850 | } | 846 | } |
851 | 847 | ||
852 | spin_lock(&sdp->sd_rindex_spin); | 848 | spin_lock(&sdp->sd_rindex_spin); |
853 | rgd->rd_free_clone = rgd->rd_rg.rg_free; | 849 | rgd->rd_free_clone = rgd->rd_free; |
854 | spin_unlock(&sdp->sd_rindex_spin); | 850 | spin_unlock(&sdp->sd_rindex_spin); |
855 | } | 851 | } |
856 | 852 | ||
@@ -1403,8 +1399,8 @@ u64 gfs2_alloc_block(struct gfs2_inode *ip, unsigned int *n) | |||
1403 | block = rgd->rd_data0 + blk; | 1399 | block = rgd->rd_data0 + blk; |
1404 | ip->i_goal = block; | 1400 | ip->i_goal = block; |
1405 | 1401 | ||
1406 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free >= *n); | 1402 | gfs2_assert_withdraw(sdp, rgd->rd_free >= *n); |
1407 | rgd->rd_rg.rg_free -= *n; | 1403 | rgd->rd_free -= *n; |
1408 | 1404 | ||
1409 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1405 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1410 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1406 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
@@ -1445,10 +1441,10 @@ u64 gfs2_alloc_di(struct gfs2_inode *dip, u64 *generation) | |||
1445 | 1441 | ||
1446 | block = rgd->rd_data0 + blk; | 1442 | block = rgd->rd_data0 + blk; |
1447 | 1443 | ||
1448 | gfs2_assert_withdraw(sdp, rgd->rd_rg.rg_free); | 1444 | gfs2_assert_withdraw(sdp, rgd->rd_free); |
1449 | rgd->rd_rg.rg_free--; | 1445 | rgd->rd_free--; |
1450 | rgd->rd_rg.rg_dinodes++; | 1446 | rgd->rd_dinodes++; |
1451 | *generation = rgd->rd_rg.rg_igeneration++; | 1447 | *generation = rgd->rd_igeneration++; |
1452 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1448 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1453 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1449 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
1454 | 1450 | ||
@@ -1481,7 +1477,7 @@ void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1481 | if (!rgd) | 1477 | if (!rgd) |
1482 | return; | 1478 | return; |
1483 | 1479 | ||
1484 | rgd->rd_rg.rg_free += blen; | 1480 | rgd->rd_free += blen; |
1485 | 1481 | ||
1486 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1482 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1487 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1483 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
@@ -1509,7 +1505,7 @@ void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1509 | if (!rgd) | 1505 | if (!rgd) |
1510 | return; | 1506 | return; |
1511 | 1507 | ||
1512 | rgd->rd_rg.rg_free += blen; | 1508 | rgd->rd_free += blen; |
1513 | 1509 | ||
1514 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1510 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1515 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1511 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
@@ -1546,10 +1542,10 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
1546 | return; | 1542 | return; |
1547 | gfs2_assert_withdraw(sdp, rgd == tmp_rgd); | 1543 | gfs2_assert_withdraw(sdp, rgd == tmp_rgd); |
1548 | 1544 | ||
1549 | if (!rgd->rd_rg.rg_dinodes) | 1545 | if (!rgd->rd_dinodes) |
1550 | gfs2_consist_rgrpd(rgd); | 1546 | gfs2_consist_rgrpd(rgd); |
1551 | rgd->rd_rg.rg_dinodes--; | 1547 | rgd->rd_dinodes--; |
1552 | rgd->rd_rg.rg_free++; | 1548 | rgd->rd_free++; |
1553 | 1549 | ||
1554 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); | 1550 | gfs2_trans_add_bh(rgd->rd_gl, rgd->rd_bits[0].bi_bh, 1); |
1555 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); | 1551 | gfs2_rgrp_out(rgd, rgd->rd_bits[0].bi_bh->b_data); |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index c3ba3d9d0aac..141b781f2fcc 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -34,76 +34,6 @@ | |||
34 | #include "util.h" | 34 | #include "util.h" |
35 | 35 | ||
36 | /** | 36 | /** |
37 | * gfs2_jindex_hold - Grab a lock on the jindex | ||
38 | * @sdp: The GFS2 superblock | ||
39 | * @ji_gh: the holder for the jindex glock | ||
40 | * | ||
41 | * This is very similar to the gfs2_rindex_hold() function, except that | ||
42 | * in general we hold the jindex lock for longer periods of time and | ||
43 | * we grab it far less frequently (in general) then the rgrp lock. | ||
44 | * | ||
45 | * Returns: errno | ||
46 | */ | ||
47 | |||
48 | int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) | ||
49 | { | ||
50 | struct gfs2_inode *dip = GFS2_I(sdp->sd_jindex); | ||
51 | struct qstr name; | ||
52 | char buf[20]; | ||
53 | struct gfs2_jdesc *jd; | ||
54 | int error; | ||
55 | |||
56 | name.name = buf; | ||
57 | |||
58 | mutex_lock(&sdp->sd_jindex_mutex); | ||
59 | |||
60 | for (;;) { | ||
61 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, ji_gh); | ||
62 | if (error) | ||
63 | break; | ||
64 | |||
65 | name.len = sprintf(buf, "journal%u", sdp->sd_journals); | ||
66 | name.hash = gfs2_disk_hash(name.name, name.len); | ||
67 | |||
68 | error = gfs2_dir_check(sdp->sd_jindex, &name, NULL); | ||
69 | if (error == -ENOENT) { | ||
70 | error = 0; | ||
71 | break; | ||
72 | } | ||
73 | |||
74 | gfs2_glock_dq_uninit(ji_gh); | ||
75 | |||
76 | if (error) | ||
77 | break; | ||
78 | |||
79 | error = -ENOMEM; | ||
80 | jd = kzalloc(sizeof(struct gfs2_jdesc), GFP_KERNEL); | ||
81 | if (!jd) | ||
82 | break; | ||
83 | |||
84 | INIT_LIST_HEAD(&jd->extent_list); | ||
85 | jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1); | ||
86 | if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { | ||
87 | if (!jd->jd_inode) | ||
88 | error = -ENOENT; | ||
89 | else | ||
90 | error = PTR_ERR(jd->jd_inode); | ||
91 | kfree(jd); | ||
92 | break; | ||
93 | } | ||
94 | |||
95 | spin_lock(&sdp->sd_jindex_spin); | ||
96 | jd->jd_jid = sdp->sd_journals++; | ||
97 | list_add_tail(&jd->jd_list, &sdp->sd_jindex_list); | ||
98 | spin_unlock(&sdp->sd_jindex_spin); | ||
99 | } | ||
100 | |||
101 | mutex_unlock(&sdp->sd_jindex_mutex); | ||
102 | |||
103 | return error; | ||
104 | } | ||
105 | |||
106 | /** | ||
107 | * gfs2_jindex_free - Clear all the journal index information | 37 | * gfs2_jindex_free - Clear all the journal index information |
108 | * @sdp: The GFS2 superblock | 38 | * @sdp: The GFS2 superblock |
109 | * | 39 | * |
@@ -166,39 +96,6 @@ struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid) | |||
166 | return jd; | 96 | return jd; |
167 | } | 97 | } |
168 | 98 | ||
169 | void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid) | ||
170 | { | ||
171 | struct gfs2_jdesc *jd; | ||
172 | |||
173 | spin_lock(&sdp->sd_jindex_spin); | ||
174 | jd = jdesc_find_i(&sdp->sd_jindex_list, jid); | ||
175 | if (jd) | ||
176 | jd->jd_dirty = 1; | ||
177 | spin_unlock(&sdp->sd_jindex_spin); | ||
178 | } | ||
179 | |||
180 | struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp) | ||
181 | { | ||
182 | struct gfs2_jdesc *jd; | ||
183 | int found = 0; | ||
184 | |||
185 | spin_lock(&sdp->sd_jindex_spin); | ||
186 | |||
187 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | ||
188 | if (jd->jd_dirty) { | ||
189 | jd->jd_dirty = 0; | ||
190 | found = 1; | ||
191 | break; | ||
192 | } | ||
193 | } | ||
194 | spin_unlock(&sdp->sd_jindex_spin); | ||
195 | |||
196 | if (!found) | ||
197 | jd = NULL; | ||
198 | |||
199 | return jd; | ||
200 | } | ||
201 | |||
202 | int gfs2_jdesc_check(struct gfs2_jdesc *jd) | 99 | int gfs2_jdesc_check(struct gfs2_jdesc *jd) |
203 | { | 100 | { |
204 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 101 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
@@ -206,14 +103,14 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd) | |||
206 | int ar; | 103 | int ar; |
207 | int error; | 104 | int error; |
208 | 105 | ||
209 | if (ip->i_di.di_size < (8 << 20) || ip->i_di.di_size > (1 << 30) || | 106 | if (ip->i_disksize < (8 << 20) || ip->i_disksize > (1 << 30) || |
210 | (ip->i_di.di_size & (sdp->sd_sb.sb_bsize - 1))) { | 107 | (ip->i_disksize & (sdp->sd_sb.sb_bsize - 1))) { |
211 | gfs2_consist_inode(ip); | 108 | gfs2_consist_inode(ip); |
212 | return -EIO; | 109 | return -EIO; |
213 | } | 110 | } |
214 | jd->jd_blocks = ip->i_di.di_size >> sdp->sd_sb.sb_bsize_shift; | 111 | jd->jd_blocks = ip->i_disksize >> sdp->sd_sb.sb_bsize_shift; |
215 | 112 | ||
216 | error = gfs2_write_alloc_required(ip, 0, ip->i_di.di_size, &ar); | 113 | error = gfs2_write_alloc_required(ip, 0, ip->i_disksize, &ar); |
217 | if (!error && ar) { | 114 | if (!error && ar) { |
218 | gfs2_consist_inode(ip); | 115 | gfs2_consist_inode(ip); |
219 | error = -EIO; | 116 | error = -EIO; |
@@ -423,137 +320,6 @@ out: | |||
423 | return error; | 320 | return error; |
424 | } | 321 | } |
425 | 322 | ||
426 | /** | ||
427 | * gfs2_statfs_i - Do a statfs | ||
428 | * @sdp: the filesystem | ||
429 | * @sg: the sg structure | ||
430 | * | ||
431 | * Returns: errno | ||
432 | */ | ||
433 | |||
434 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
435 | { | ||
436 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
437 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | ||
438 | |||
439 | spin_lock(&sdp->sd_statfs_spin); | ||
440 | |||
441 | *sc = *m_sc; | ||
442 | sc->sc_total += l_sc->sc_total; | ||
443 | sc->sc_free += l_sc->sc_free; | ||
444 | sc->sc_dinodes += l_sc->sc_dinodes; | ||
445 | |||
446 | spin_unlock(&sdp->sd_statfs_spin); | ||
447 | |||
448 | if (sc->sc_free < 0) | ||
449 | sc->sc_free = 0; | ||
450 | if (sc->sc_free > sc->sc_total) | ||
451 | sc->sc_free = sc->sc_total; | ||
452 | if (sc->sc_dinodes < 0) | ||
453 | sc->sc_dinodes = 0; | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | /** | ||
459 | * statfs_fill - fill in the sg for a given RG | ||
460 | * @rgd: the RG | ||
461 | * @sc: the sc structure | ||
462 | * | ||
463 | * Returns: 0 on success, -ESTALE if the LVB is invalid | ||
464 | */ | ||
465 | |||
466 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | ||
467 | struct gfs2_statfs_change_host *sc) | ||
468 | { | ||
469 | gfs2_rgrp_verify(rgd); | ||
470 | sc->sc_total += rgd->rd_data; | ||
471 | sc->sc_free += rgd->rd_rg.rg_free; | ||
472 | sc->sc_dinodes += rgd->rd_rg.rg_dinodes; | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | /** | ||
477 | * gfs2_statfs_slow - Stat a filesystem using asynchronous locking | ||
478 | * @sdp: the filesystem | ||
479 | * @sc: the sc info that will be returned | ||
480 | * | ||
481 | * Any error (other than a signal) will cause this routine to fall back | ||
482 | * to the synchronous version. | ||
483 | * | ||
484 | * FIXME: This really shouldn't busy wait like this. | ||
485 | * | ||
486 | * Returns: errno | ||
487 | */ | ||
488 | |||
489 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) | ||
490 | { | ||
491 | struct gfs2_holder ri_gh; | ||
492 | struct gfs2_rgrpd *rgd_next; | ||
493 | struct gfs2_holder *gha, *gh; | ||
494 | unsigned int slots = 64; | ||
495 | unsigned int x; | ||
496 | int done; | ||
497 | int error = 0, err; | ||
498 | |||
499 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); | ||
500 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | ||
501 | if (!gha) | ||
502 | return -ENOMEM; | ||
503 | |||
504 | error = gfs2_rindex_hold(sdp, &ri_gh); | ||
505 | if (error) | ||
506 | goto out; | ||
507 | |||
508 | rgd_next = gfs2_rgrpd_get_first(sdp); | ||
509 | |||
510 | for (;;) { | ||
511 | done = 1; | ||
512 | |||
513 | for (x = 0; x < slots; x++) { | ||
514 | gh = gha + x; | ||
515 | |||
516 | if (gh->gh_gl && gfs2_glock_poll(gh)) { | ||
517 | err = gfs2_glock_wait(gh); | ||
518 | if (err) { | ||
519 | gfs2_holder_uninit(gh); | ||
520 | error = err; | ||
521 | } else { | ||
522 | if (!error) | ||
523 | error = statfs_slow_fill( | ||
524 | gh->gh_gl->gl_object, sc); | ||
525 | gfs2_glock_dq_uninit(gh); | ||
526 | } | ||
527 | } | ||
528 | |||
529 | if (gh->gh_gl) | ||
530 | done = 0; | ||
531 | else if (rgd_next && !error) { | ||
532 | error = gfs2_glock_nq_init(rgd_next->rd_gl, | ||
533 | LM_ST_SHARED, | ||
534 | GL_ASYNC, | ||
535 | gh); | ||
536 | rgd_next = gfs2_rgrpd_get_next(rgd_next); | ||
537 | done = 0; | ||
538 | } | ||
539 | |||
540 | if (signal_pending(current)) | ||
541 | error = -ERESTARTSYS; | ||
542 | } | ||
543 | |||
544 | if (done) | ||
545 | break; | ||
546 | |||
547 | yield(); | ||
548 | } | ||
549 | |||
550 | gfs2_glock_dq_uninit(&ri_gh); | ||
551 | |||
552 | out: | ||
553 | kfree(gha); | ||
554 | return error; | ||
555 | } | ||
556 | |||
557 | struct lfcc { | 323 | struct lfcc { |
558 | struct list_head list; | 324 | struct list_head list; |
559 | struct gfs2_holder gh; | 325 | struct gfs2_holder gh; |
@@ -580,10 +346,6 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, | |||
580 | struct gfs2_log_header_host lh; | 346 | struct gfs2_log_header_host lh; |
581 | int error; | 347 | int error; |
582 | 348 | ||
583 | error = gfs2_jindex_hold(sdp, &ji_gh); | ||
584 | if (error) | ||
585 | return error; | ||
586 | |||
587 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | 349 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
588 | lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); | 350 | lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); |
589 | if (!lfcc) { | 351 | if (!lfcc) { |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index 50a4c9b1215e..f6b8b00ad881 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
@@ -10,6 +10,8 @@ | |||
10 | #ifndef __SUPER_DOT_H__ | 10 | #ifndef __SUPER_DOT_H__ |
11 | #define __SUPER_DOT_H__ | 11 | #define __SUPER_DOT_H__ |
12 | 12 | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/dcache.h> | ||
13 | #include "incore.h" | 15 | #include "incore.h" |
14 | 16 | ||
15 | void gfs2_lm_unmount(struct gfs2_sbd *sdp); | 17 | void gfs2_lm_unmount(struct gfs2_sbd *sdp); |
@@ -23,12 +25,9 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) | |||
23 | return x; | 25 | return x; |
24 | } | 26 | } |
25 | 27 | ||
26 | int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh); | ||
27 | void gfs2_jindex_free(struct gfs2_sbd *sdp); | 28 | void gfs2_jindex_free(struct gfs2_sbd *sdp); |
28 | 29 | ||
29 | struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); | 30 | struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); |
30 | void gfs2_jdesc_make_dirty(struct gfs2_sbd *sdp, unsigned int jid); | ||
31 | struct gfs2_jdesc *gfs2_jdesc_find_dirty(struct gfs2_sbd *sdp); | ||
32 | int gfs2_jdesc_check(struct gfs2_jdesc *jd); | 31 | int gfs2_jdesc_check(struct gfs2_jdesc *jd); |
33 | 32 | ||
34 | int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename, | 33 | int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename, |
@@ -40,11 +39,15 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp); | |||
40 | void gfs2_statfs_change(struct gfs2_sbd *sdp, | 39 | void gfs2_statfs_change(struct gfs2_sbd *sdp, |
41 | s64 total, s64 free, s64 dinodes); | 40 | s64 total, s64 free, s64 dinodes); |
42 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); | 41 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); |
43 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); | ||
44 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); | ||
45 | 42 | ||
46 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); | 43 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); |
47 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); | 44 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); |
48 | 45 | ||
46 | extern struct file_system_type gfs2_fs_type; | ||
47 | extern struct file_system_type gfs2meta_fs_type; | ||
48 | extern const struct export_operations gfs2_export_ops; | ||
49 | extern const struct super_operations gfs2_super_ops; | ||
50 | extern struct dentry_operations gfs2_dops; | ||
51 | |||
49 | #endif /* __SUPER_DOT_H__ */ | 52 | #endif /* __SUPER_DOT_H__ */ |
50 | 53 | ||
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 7e1879f1a02c..26c1fa777a95 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -26,9 +26,6 @@ | |||
26 | #include "quota.h" | 26 | #include "quota.h" |
27 | #include "util.h" | 27 | #include "util.h" |
28 | 28 | ||
29 | char *gfs2_sys_margs; | ||
30 | spinlock_t gfs2_sys_margs_lock; | ||
31 | |||
32 | static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) | 29 | static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) |
33 | { | 30 | { |
34 | return snprintf(buf, PAGE_SIZE, "%u:%u\n", | 31 | return snprintf(buf, PAGE_SIZE, "%u:%u\n", |
@@ -263,7 +260,6 @@ ARGS_ATTR(localcaching, "%d\n"); | |||
263 | ARGS_ATTR(localflocks, "%d\n"); | 260 | ARGS_ATTR(localflocks, "%d\n"); |
264 | ARGS_ATTR(debug, "%d\n"); | 261 | ARGS_ATTR(debug, "%d\n"); |
265 | ARGS_ATTR(upgrade, "%d\n"); | 262 | ARGS_ATTR(upgrade, "%d\n"); |
266 | ARGS_ATTR(num_glockd, "%u\n"); | ||
267 | ARGS_ATTR(posix_acl, "%d\n"); | 263 | ARGS_ATTR(posix_acl, "%d\n"); |
268 | ARGS_ATTR(quota, "%u\n"); | 264 | ARGS_ATTR(quota, "%u\n"); |
269 | ARGS_ATTR(suiddir, "%d\n"); | 265 | ARGS_ATTR(suiddir, "%d\n"); |
@@ -279,7 +275,6 @@ static struct attribute *args_attrs[] = { | |||
279 | &args_attr_localflocks.attr, | 275 | &args_attr_localflocks.attr, |
280 | &args_attr_debug.attr, | 276 | &args_attr_debug.attr, |
281 | &args_attr_upgrade.attr, | 277 | &args_attr_upgrade.attr, |
282 | &args_attr_num_glockd.attr, | ||
283 | &args_attr_posix_acl.attr, | 278 | &args_attr_posix_acl.attr, |
284 | &args_attr_quota.attr, | 279 | &args_attr_quota.attr, |
285 | &args_attr_suiddir.attr, | 280 | &args_attr_suiddir.attr, |
@@ -288,30 +283,6 @@ static struct attribute *args_attrs[] = { | |||
288 | }; | 283 | }; |
289 | 284 | ||
290 | /* | 285 | /* |
291 | * display counters from superblock | ||
292 | */ | ||
293 | |||
294 | struct counters_attr { | ||
295 | struct attribute attr; | ||
296 | ssize_t (*show)(struct gfs2_sbd *, char *); | ||
297 | }; | ||
298 | |||
299 | #define COUNTERS_ATTR(name, fmt) \ | ||
300 | static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ | ||
301 | { \ | ||
302 | return snprintf(buf, PAGE_SIZE, fmt, \ | ||
303 | (unsigned int)atomic_read(&sdp->sd_##name)); \ | ||
304 | } \ | ||
305 | static struct counters_attr counters_attr_##name = __ATTR_RO(name) | ||
306 | |||
307 | COUNTERS_ATTR(reclaimed, "%u\n"); | ||
308 | |||
309 | static struct attribute *counters_attrs[] = { | ||
310 | &counters_attr_reclaimed.attr, | ||
311 | NULL, | ||
312 | }; | ||
313 | |||
314 | /* | ||
315 | * get and set struct gfs2_tune fields | 286 | * get and set struct gfs2_tune fields |
316 | */ | 287 | */ |
317 | 288 | ||
@@ -393,7 +364,6 @@ static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | |||
393 | } \ | 364 | } \ |
394 | TUNE_ATTR_2(name, name##_store) | 365 | TUNE_ATTR_2(name, name##_store) |
395 | 366 | ||
396 | TUNE_ATTR(demote_secs, 0); | ||
397 | TUNE_ATTR(incore_log_blocks, 0); | 367 | TUNE_ATTR(incore_log_blocks, 0); |
398 | TUNE_ATTR(log_flush_secs, 0); | 368 | TUNE_ATTR(log_flush_secs, 0); |
399 | TUNE_ATTR(quota_warn_period, 0); | 369 | TUNE_ATTR(quota_warn_period, 0); |
@@ -408,11 +378,9 @@ TUNE_ATTR(stall_secs, 1); | |||
408 | TUNE_ATTR(statfs_quantum, 1); | 378 | TUNE_ATTR(statfs_quantum, 1); |
409 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); | 379 | TUNE_ATTR_DAEMON(recoverd_secs, recoverd_process); |
410 | TUNE_ATTR_DAEMON(logd_secs, logd_process); | 380 | TUNE_ATTR_DAEMON(logd_secs, logd_process); |
411 | TUNE_ATTR_DAEMON(quotad_secs, quotad_process); | ||
412 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); | 381 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); |
413 | 382 | ||
414 | static struct attribute *tune_attrs[] = { | 383 | static struct attribute *tune_attrs[] = { |
415 | &tune_attr_demote_secs.attr, | ||
416 | &tune_attr_incore_log_blocks.attr, | 384 | &tune_attr_incore_log_blocks.attr, |
417 | &tune_attr_log_flush_secs.attr, | 385 | &tune_attr_log_flush_secs.attr, |
418 | &tune_attr_quota_warn_period.attr, | 386 | &tune_attr_quota_warn_period.attr, |
@@ -426,7 +394,6 @@ static struct attribute *tune_attrs[] = { | |||
426 | &tune_attr_statfs_quantum.attr, | 394 | &tune_attr_statfs_quantum.attr, |
427 | &tune_attr_recoverd_secs.attr, | 395 | &tune_attr_recoverd_secs.attr, |
428 | &tune_attr_logd_secs.attr, | 396 | &tune_attr_logd_secs.attr, |
429 | &tune_attr_quotad_secs.attr, | ||
430 | &tune_attr_quota_scale.attr, | 397 | &tune_attr_quota_scale.attr, |
431 | &tune_attr_new_files_jdata.attr, | 398 | &tune_attr_new_files_jdata.attr, |
432 | NULL, | 399 | NULL, |
@@ -437,11 +404,6 @@ static struct attribute_group lockstruct_group = { | |||
437 | .attrs = lockstruct_attrs, | 404 | .attrs = lockstruct_attrs, |
438 | }; | 405 | }; |
439 | 406 | ||
440 | static struct attribute_group counters_group = { | ||
441 | .name = "counters", | ||
442 | .attrs = counters_attrs, | ||
443 | }; | ||
444 | |||
445 | static struct attribute_group args_group = { | 407 | static struct attribute_group args_group = { |
446 | .name = "args", | 408 | .name = "args", |
447 | .attrs = args_attrs, | 409 | .attrs = args_attrs, |
@@ -466,13 +428,9 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
466 | if (error) | 428 | if (error) |
467 | goto fail_reg; | 429 | goto fail_reg; |
468 | 430 | ||
469 | error = sysfs_create_group(&sdp->sd_kobj, &counters_group); | ||
470 | if (error) | ||
471 | goto fail_lockstruct; | ||
472 | |||
473 | error = sysfs_create_group(&sdp->sd_kobj, &args_group); | 431 | error = sysfs_create_group(&sdp->sd_kobj, &args_group); |
474 | if (error) | 432 | if (error) |
475 | goto fail_counters; | 433 | goto fail_lockstruct; |
476 | 434 | ||
477 | error = sysfs_create_group(&sdp->sd_kobj, &tune_group); | 435 | error = sysfs_create_group(&sdp->sd_kobj, &tune_group); |
478 | if (error) | 436 | if (error) |
@@ -483,8 +441,6 @@ int gfs2_sys_fs_add(struct gfs2_sbd *sdp) | |||
483 | 441 | ||
484 | fail_args: | 442 | fail_args: |
485 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | 443 | sysfs_remove_group(&sdp->sd_kobj, &args_group); |
486 | fail_counters: | ||
487 | sysfs_remove_group(&sdp->sd_kobj, &counters_group); | ||
488 | fail_lockstruct: | 444 | fail_lockstruct: |
489 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | 445 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); |
490 | fail_reg: | 446 | fail_reg: |
@@ -498,16 +454,27 @@ void gfs2_sys_fs_del(struct gfs2_sbd *sdp) | |||
498 | { | 454 | { |
499 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); | 455 | sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
500 | sysfs_remove_group(&sdp->sd_kobj, &args_group); | 456 | sysfs_remove_group(&sdp->sd_kobj, &args_group); |
501 | sysfs_remove_group(&sdp->sd_kobj, &counters_group); | ||
502 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); | 457 | sysfs_remove_group(&sdp->sd_kobj, &lockstruct_group); |
503 | kobject_put(&sdp->sd_kobj); | 458 | kobject_put(&sdp->sd_kobj); |
504 | } | 459 | } |
505 | 460 | ||
461 | static int gfs2_uevent(struct kset *kset, struct kobject *kobj, | ||
462 | struct kobj_uevent_env *env) | ||
463 | { | ||
464 | struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); | ||
465 | add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name); | ||
466 | add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name); | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | static struct kset_uevent_ops gfs2_uevent_ops = { | ||
471 | .uevent = gfs2_uevent, | ||
472 | }; | ||
473 | |||
474 | |||
506 | int gfs2_sys_init(void) | 475 | int gfs2_sys_init(void) |
507 | { | 476 | { |
508 | gfs2_sys_margs = NULL; | 477 | gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj); |
509 | spin_lock_init(&gfs2_sys_margs_lock); | ||
510 | gfs2_kset = kset_create_and_add("gfs2", NULL, fs_kobj); | ||
511 | if (!gfs2_kset) | 478 | if (!gfs2_kset) |
512 | return -ENOMEM; | 479 | return -ENOMEM; |
513 | return 0; | 480 | return 0; |
@@ -515,7 +482,6 @@ int gfs2_sys_init(void) | |||
515 | 482 | ||
516 | void gfs2_sys_uninit(void) | 483 | void gfs2_sys_uninit(void) |
517 | { | 484 | { |
518 | kfree(gfs2_sys_margs); | ||
519 | kset_unregister(gfs2_kset); | 485 | kset_unregister(gfs2_kset); |
520 | } | 486 | } |
521 | 487 | ||
diff --git a/fs/gfs2/sys.h b/fs/gfs2/sys.h index 1ca8cdac5304..e94560e836d7 100644 --- a/fs/gfs2/sys.h +++ b/fs/gfs2/sys.h | |||
@@ -13,10 +13,6 @@ | |||
13 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
14 | struct gfs2_sbd; | 14 | struct gfs2_sbd; |
15 | 15 | ||
16 | /* Allow args to be passed to GFS2 when using an initial ram disk */ | ||
17 | extern char *gfs2_sys_margs; | ||
18 | extern spinlock_t gfs2_sys_margs_lock; | ||
19 | |||
20 | int gfs2_sys_fs_add(struct gfs2_sbd *sdp); | 16 | int gfs2_sys_fs_add(struct gfs2_sbd *sdp); |
21 | void gfs2_sys_fs_del(struct gfs2_sbd *sdp); | 17 | void gfs2_sys_fs_del(struct gfs2_sbd *sdp); |
22 | 18 | ||
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index d31e355c61fb..374f50e95496 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c | |||
@@ -25,6 +25,7 @@ struct kmem_cache *gfs2_glock_cachep __read_mostly; | |||
25 | struct kmem_cache *gfs2_inode_cachep __read_mostly; | 25 | struct kmem_cache *gfs2_inode_cachep __read_mostly; |
26 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; | 26 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; |
27 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; | 27 | struct kmem_cache *gfs2_rgrpd_cachep __read_mostly; |
28 | struct kmem_cache *gfs2_quotad_cachep __read_mostly; | ||
28 | 29 | ||
29 | void gfs2_assert_i(struct gfs2_sbd *sdp) | 30 | void gfs2_assert_i(struct gfs2_sbd *sdp) |
30 | { | 31 | { |
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index 7f48576289c9..33e96b0ce9ab 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h | |||
@@ -148,6 +148,7 @@ extern struct kmem_cache *gfs2_glock_cachep; | |||
148 | extern struct kmem_cache *gfs2_inode_cachep; | 148 | 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 | 152 | ||
152 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, | 153 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, |
153 | unsigned int *p) | 154 | unsigned int *p) |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 43e8b2c0664b..cc3f1aa1cf7b 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -231,7 +231,8 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg) | |||
231 | #define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits) | 231 | #define blk_to_logical(inode, blk) (blk << (inode)->i_blkbits) |
232 | #define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits); | 232 | #define logical_to_blk(inode, offset) (offset >> (inode)->i_blkbits); |
233 | 233 | ||
234 | /* | 234 | /** |
235 | * __generic_block_fiemap - FIEMAP for block based inodes (no locking) | ||
235 | * @inode - the inode to map | 236 | * @inode - the inode to map |
236 | * @arg - the pointer to userspace where we copy everything to | 237 | * @arg - the pointer to userspace where we copy everything to |
237 | * @get_block - the fs's get_block function | 238 | * @get_block - the fs's get_block function |
@@ -242,11 +243,15 @@ static int ioctl_fiemap(struct file *filp, unsigned long arg) | |||
242 | * | 243 | * |
243 | * If it is possible to have data blocks beyond a hole past @inode->i_size, then | 244 | * If it is possible to have data blocks beyond a hole past @inode->i_size, then |
244 | * please do not use this function, it will stop at the first unmapped block | 245 | * please do not use this function, it will stop at the first unmapped block |
245 | * beyond i_size | 246 | * beyond i_size. |
247 | * | ||
248 | * If you use this function directly, you need to do your own locking. Use | ||
249 | * generic_block_fiemap if you want the locking done for you. | ||
246 | */ | 250 | */ |
247 | int generic_block_fiemap(struct inode *inode, | 251 | |
248 | struct fiemap_extent_info *fieinfo, u64 start, | 252 | int __generic_block_fiemap(struct inode *inode, |
249 | u64 len, get_block_t *get_block) | 253 | struct fiemap_extent_info *fieinfo, u64 start, |
254 | u64 len, get_block_t *get_block) | ||
250 | { | 255 | { |
251 | struct buffer_head tmp; | 256 | struct buffer_head tmp; |
252 | unsigned int start_blk; | 257 | unsigned int start_blk; |
@@ -260,9 +265,6 @@ int generic_block_fiemap(struct inode *inode, | |||
260 | 265 | ||
261 | start_blk = logical_to_blk(inode, start); | 266 | start_blk = logical_to_blk(inode, start); |
262 | 267 | ||
263 | /* guard against change */ | ||
264 | mutex_lock(&inode->i_mutex); | ||
265 | |||
266 | length = (long long)min_t(u64, len, i_size_read(inode)); | 268 | length = (long long)min_t(u64, len, i_size_read(inode)); |
267 | map_len = length; | 269 | map_len = length; |
268 | 270 | ||
@@ -334,14 +336,36 @@ int generic_block_fiemap(struct inode *inode, | |||
334 | cond_resched(); | 336 | cond_resched(); |
335 | } while (1); | 337 | } while (1); |
336 | 338 | ||
337 | mutex_unlock(&inode->i_mutex); | ||
338 | |||
339 | /* if ret is 1 then we just hit the end of the extent array */ | 339 | /* if ret is 1 then we just hit the end of the extent array */ |
340 | if (ret == 1) | 340 | if (ret == 1) |
341 | ret = 0; | 341 | ret = 0; |
342 | 342 | ||
343 | return ret; | 343 | return ret; |
344 | } | 344 | } |
345 | EXPORT_SYMBOL(__generic_block_fiemap); | ||
346 | |||
347 | /** | ||
348 | * generic_block_fiemap - FIEMAP for block based inodes | ||
349 | * @inode: The inode to map | ||
350 | * @fieinfo: The mapping information | ||
351 | * @start: The initial block to map | ||
352 | * @len: The length of the extect to attempt to map | ||
353 | * @get_block: The block mapping function for the fs | ||
354 | * | ||
355 | * Calls __generic_block_fiemap to map the inode, after taking | ||
356 | * the inode's mutex lock. | ||
357 | */ | ||
358 | |||
359 | int generic_block_fiemap(struct inode *inode, | ||
360 | struct fiemap_extent_info *fieinfo, u64 start, | ||
361 | u64 len, get_block_t *get_block) | ||
362 | { | ||
363 | int ret; | ||
364 | mutex_lock(&inode->i_mutex); | ||
365 | ret = __generic_block_fiemap(inode, fieinfo, start, len, get_block); | ||
366 | mutex_unlock(&inode->i_mutex); | ||
367 | return ret; | ||
368 | } | ||
345 | EXPORT_SYMBOL(generic_block_fiemap); | 369 | EXPORT_SYMBOL(generic_block_fiemap); |
346 | 370 | ||
347 | #endif /* CONFIG_BLOCK */ | 371 | #endif /* CONFIG_BLOCK */ |