diff options
Diffstat (limited to 'fs')
320 files changed, 5365 insertions, 4124 deletions
diff --git a/fs/9p/conv.c b/fs/9p/conv.c index 56d88c1a09c5..a3ed571eee31 100644 --- a/fs/9p/conv.c +++ b/fs/9p/conv.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/sched.h> | ||
30 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
32 | #include "debug.h" | 33 | #include "debug.h" |
diff --git a/fs/9p/fcall.c b/fs/9p/fcall.c index 8556097fcda8..dc336a67592f 100644 --- a/fs/9p/fcall.c +++ b/fs/9p/fcall.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/sched.h> | ||
30 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
31 | 32 | ||
32 | #include "debug.h" | 33 | #include "debug.h" |
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 70492ccb4385..27507201f9e7 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/sched.h> | ||
26 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
27 | 28 | ||
28 | #include "debug.h" | 29 | #include "debug.h" |
diff --git a/fs/9p/mux.c b/fs/9p/mux.c index 90a79c784549..944273c3dbff 100644 --- a/fs/9p/mux.c +++ b/fs/9p/mux.c | |||
@@ -110,8 +110,8 @@ struct v9fs_mux_rpc { | |||
110 | }; | 110 | }; |
111 | 111 | ||
112 | static int v9fs_poll_proc(void *); | 112 | static int v9fs_poll_proc(void *); |
113 | static void v9fs_read_work(void *); | 113 | static void v9fs_read_work(struct work_struct *work); |
114 | static void v9fs_write_work(void *); | 114 | static void v9fs_write_work(struct work_struct *work); |
115 | static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, | 115 | static void v9fs_pollwait(struct file *filp, wait_queue_head_t * wait_address, |
116 | poll_table * p); | 116 | poll_table * p); |
117 | static u16 v9fs_mux_get_tag(struct v9fs_mux_data *); | 117 | static u16 v9fs_mux_get_tag(struct v9fs_mux_data *); |
@@ -297,8 +297,8 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize, | |||
297 | m->rbuf = NULL; | 297 | m->rbuf = NULL; |
298 | m->wpos = m->wsize = 0; | 298 | m->wpos = m->wsize = 0; |
299 | m->wbuf = NULL; | 299 | m->wbuf = NULL; |
300 | INIT_WORK(&m->rq, v9fs_read_work, m); | 300 | INIT_WORK(&m->rq, v9fs_read_work); |
301 | INIT_WORK(&m->wq, v9fs_write_work, m); | 301 | INIT_WORK(&m->wq, v9fs_write_work); |
302 | m->wsched = 0; | 302 | m->wsched = 0; |
303 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); | 303 | memset(&m->poll_waddr, 0, sizeof(m->poll_waddr)); |
304 | m->poll_task = NULL; | 304 | m->poll_task = NULL; |
@@ -458,13 +458,13 @@ static int v9fs_poll_proc(void *a) | |||
458 | /** | 458 | /** |
459 | * v9fs_write_work - called when a transport can send some data | 459 | * v9fs_write_work - called when a transport can send some data |
460 | */ | 460 | */ |
461 | static void v9fs_write_work(void *a) | 461 | static void v9fs_write_work(struct work_struct *work) |
462 | { | 462 | { |
463 | int n, err; | 463 | int n, err; |
464 | struct v9fs_mux_data *m; | 464 | struct v9fs_mux_data *m; |
465 | struct v9fs_req *req; | 465 | struct v9fs_req *req; |
466 | 466 | ||
467 | m = a; | 467 | m = container_of(work, struct v9fs_mux_data, wq); |
468 | 468 | ||
469 | if (m->err < 0) { | 469 | if (m->err < 0) { |
470 | clear_bit(Wworksched, &m->wsched); | 470 | clear_bit(Wworksched, &m->wsched); |
@@ -564,7 +564,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
564 | /** | 564 | /** |
565 | * v9fs_read_work - called when there is some data to be read from a transport | 565 | * v9fs_read_work - called when there is some data to be read from a transport |
566 | */ | 566 | */ |
567 | static void v9fs_read_work(void *a) | 567 | static void v9fs_read_work(struct work_struct *work) |
568 | { | 568 | { |
569 | int n, err; | 569 | int n, err; |
570 | struct v9fs_mux_data *m; | 570 | struct v9fs_mux_data *m; |
@@ -572,7 +572,7 @@ static void v9fs_read_work(void *a) | |||
572 | struct v9fs_fcall *rcall; | 572 | struct v9fs_fcall *rcall; |
573 | char *rbuf; | 573 | char *rbuf; |
574 | 574 | ||
575 | m = a; | 575 | m = container_of(work, struct v9fs_mux_data, rq); |
576 | 576 | ||
577 | if (m->err < 0) | 577 | if (m->err < 0) |
578 | return; | 578 | return; |
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 0f628041e3f7..0b96fae8b479 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/sched.h> | ||
29 | #include <linux/parser.h> | 30 | #include <linux/parser.h> |
30 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
31 | 32 | ||
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c index e32d5971039b..905c882f4e2f 100644 --- a/fs/9p/vfs_dir.c +++ b/fs/9p/vfs_dir.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/stat.h> | 30 | #include <linux/stat.h> |
31 | #include <linux/string.h> | 31 | #include <linux/string.h> |
32 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
33 | #include <linux/sched.h> | ||
33 | #include <linux/inet.h> | 34 | #include <linux/inet.h> |
34 | #include <linux/idr.h> | 35 | #include <linux/idr.h> |
35 | 36 | ||
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index c3c47eda7574..79e6f9cd7340 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
29 | #include <linux/sched.h> | ||
29 | #include <linux/file.h> | 30 | #include <linux/file.h> |
30 | #include <linux/stat.h> | 31 | #include <linux/stat.h> |
31 | #include <linux/string.h> | 32 | #include <linux/string.h> |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 5241c600ce28..18f26cdfd882 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -256,7 +256,7 @@ static int | |||
256 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, | 256 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm, |
257 | u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) | 257 | u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) |
258 | { | 258 | { |
259 | u32 fid; | 259 | int fid; |
260 | int err; | 260 | int err; |
261 | struct v9fs_fcall *fcall; | 261 | struct v9fs_fcall *fcall; |
262 | 262 | ||
@@ -310,7 +310,7 @@ static struct v9fs_fid* | |||
310 | v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) | 310 | v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry) |
311 | { | 311 | { |
312 | int err; | 312 | int err; |
313 | u32 nfid; | 313 | int nfid; |
314 | struct v9fs_fid *ret; | 314 | struct v9fs_fid *ret; |
315 | struct v9fs_fcall *fcall; | 315 | struct v9fs_fcall *fcall; |
316 | 316 | ||
diff --git a/fs/Kconfig b/fs/Kconfig index 133dcc8a4150..b3b5aa0edff9 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -972,7 +972,7 @@ config SYSFS | |||
972 | 972 | ||
973 | Some system agents rely on the information in sysfs to operate. | 973 | Some system agents rely on the information in sysfs to operate. |
974 | /sbin/hotplug uses device and object attributes in sysfs to assist in | 974 | /sbin/hotplug uses device and object attributes in sysfs to assist in |
975 | delegating policy decisions, like persistantly naming devices. | 975 | delegating policy decisions, like persistently naming devices. |
976 | 976 | ||
977 | sysfs is currently used by the block subsystem to mount the root | 977 | sysfs is currently used by the block subsystem to mount the root |
978 | partition. If sysfs is disabled you must specify the boot device on | 978 | partition. If sysfs is disabled you must specify the boot device on |
@@ -1145,7 +1145,7 @@ config BEFS_FS | |||
1145 | help | 1145 | help |
1146 | The BeOS File System (BeFS) is the native file system of Be, Inc's | 1146 | The BeOS File System (BeFS) is the native file system of Be, Inc's |
1147 | BeOS. Notable features include support for arbitrary attributes | 1147 | BeOS. Notable features include support for arbitrary attributes |
1148 | on files and directories, and database-like indeces on selected | 1148 | on files and directories, and database-like indices on selected |
1149 | attributes. (Also note that this driver doesn't make those features | 1149 | attributes. (Also note that this driver doesn't make those features |
1150 | available at this time). It is a 64 bit filesystem, so it supports | 1150 | available at this time). It is a 64 bit filesystem, so it supports |
1151 | extremely large volumes and files. | 1151 | extremely large volumes and files. |
@@ -2060,8 +2060,7 @@ config CODA_FS_OLD_API | |||
2060 | For most cases you probably want to say N. | 2060 | For most cases you probably want to say N. |
2061 | 2061 | ||
2062 | config AFS_FS | 2062 | config AFS_FS |
2063 | # for fs/nls/Config.in | 2063 | tristate "Andrew File System support (AFS) (EXPERIMENTAL)" |
2064 | tristate "Andrew File System support (AFS) (Experimental)" | ||
2065 | depends on INET && EXPERIMENTAL | 2064 | depends on INET && EXPERIMENTAL |
2066 | select RXRPC | 2065 | select RXRPC |
2067 | help | 2066 | help |
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index 9ade139086fc..5023351a7afe 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
@@ -36,7 +36,7 @@ void __adfs_error(struct super_block *sb, const char *function, const char *fmt, | |||
36 | va_list args; | 36 | va_list args; |
37 | 37 | ||
38 | va_start(args, fmt); | 38 | va_start(args, fmt); |
39 | vsprintf(error_buf, fmt, args); | 39 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
40 | va_end(args); | 40 | va_end(args); |
41 | 41 | ||
42 | printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: %s\n", | 42 | printk(KERN_CRIT "ADFS-fs error (device %s)%s%s: %s\n", |
@@ -212,12 +212,12 @@ static int adfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
212 | return 0; | 212 | return 0; |
213 | } | 213 | } |
214 | 214 | ||
215 | static kmem_cache_t *adfs_inode_cachep; | 215 | static struct kmem_cache *adfs_inode_cachep; |
216 | 216 | ||
217 | static struct inode *adfs_alloc_inode(struct super_block *sb) | 217 | static struct inode *adfs_alloc_inode(struct super_block *sb) |
218 | { | 218 | { |
219 | struct adfs_inode_info *ei; | 219 | struct adfs_inode_info *ei; |
220 | ei = (struct adfs_inode_info *)kmem_cache_alloc(adfs_inode_cachep, SLAB_KERNEL); | 220 | ei = (struct adfs_inode_info *)kmem_cache_alloc(adfs_inode_cachep, GFP_KERNEL); |
221 | if (!ei) | 221 | if (!ei) |
222 | return NULL; | 222 | return NULL; |
223 | return &ei->vfs_inode; | 223 | return &ei->vfs_inode; |
@@ -228,7 +228,7 @@ static void adfs_destroy_inode(struct inode *inode) | |||
228 | kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); | 228 | kmem_cache_free(adfs_inode_cachep, ADFS_I(inode)); |
229 | } | 229 | } |
230 | 230 | ||
231 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 231 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
232 | { | 232 | { |
233 | struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; | 233 | struct adfs_inode_info *ei = (struct adfs_inode_info *) foo; |
234 | 234 | ||
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index ccd624ef4272..f4de4b98004f 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c | |||
@@ -445,7 +445,7 @@ affs_error(struct super_block *sb, const char *function, const char *fmt, ...) | |||
445 | va_list args; | 445 | va_list args; |
446 | 446 | ||
447 | va_start(args,fmt); | 447 | va_start(args,fmt); |
448 | vsprintf(ErrorBuffer,fmt,args); | 448 | vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); |
449 | va_end(args); | 449 | va_end(args); |
450 | 450 | ||
451 | printk(KERN_CRIT "AFFS error (device %s): %s(): %s\n", sb->s_id, | 451 | printk(KERN_CRIT "AFFS error (device %s): %s(): %s\n", sb->s_id, |
@@ -461,7 +461,7 @@ affs_warning(struct super_block *sb, const char *function, const char *fmt, ...) | |||
461 | va_list args; | 461 | va_list args; |
462 | 462 | ||
463 | va_start(args,fmt); | 463 | va_start(args,fmt); |
464 | vsprintf(ErrorBuffer,fmt,args); | 464 | vsnprintf(ErrorBuffer,sizeof(ErrorBuffer),fmt,args); |
465 | va_end(args); | 465 | va_end(args); |
466 | 466 | ||
467 | printk(KERN_WARNING "AFFS warning (device %s): %s(): %s\n", sb->s_id, | 467 | printk(KERN_WARNING "AFFS warning (device %s): %s(): %s\n", sb->s_id, |
diff --git a/fs/affs/bitmap.c b/fs/affs/bitmap.c index b0b953683c1a..b330009fe42d 100644 --- a/fs/affs/bitmap.c +++ b/fs/affs/bitmap.c | |||
@@ -289,12 +289,11 @@ int affs_init_bitmap(struct super_block *sb, int *flags) | |||
289 | sbi->s_bmap_count = (sbi->s_partition_size - sbi->s_reserved + | 289 | sbi->s_bmap_count = (sbi->s_partition_size - sbi->s_reserved + |
290 | sbi->s_bmap_bits - 1) / sbi->s_bmap_bits; | 290 | sbi->s_bmap_bits - 1) / sbi->s_bmap_bits; |
291 | size = sbi->s_bmap_count * sizeof(*bm); | 291 | size = sbi->s_bmap_count * sizeof(*bm); |
292 | bm = sbi->s_bitmap = kmalloc(size, GFP_KERNEL); | 292 | bm = sbi->s_bitmap = kzalloc(size, GFP_KERNEL); |
293 | if (!sbi->s_bitmap) { | 293 | if (!sbi->s_bitmap) { |
294 | printk(KERN_ERR "AFFS: Bitmap allocation failed\n"); | 294 | printk(KERN_ERR "AFFS: Bitmap allocation failed\n"); |
295 | return -ENOMEM; | 295 | return -ENOMEM; |
296 | } | 296 | } |
297 | memset(sbi->s_bitmap, 0, size); | ||
298 | 297 | ||
299 | bmap_blk = (__be32 *)sbi->s_root_bh->b_data; | 298 | bmap_blk = (__be32 *)sbi->s_root_bh->b_data; |
300 | blk = sb->s_blocksize / 4 - 49; | 299 | blk = sb->s_blocksize / 4 - 49; |
diff --git a/fs/affs/super.c b/fs/affs/super.c index 5ea72c3a16c3..3de93e799949 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -66,12 +66,12 @@ affs_write_super(struct super_block *sb) | |||
66 | pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean); | 66 | pr_debug("AFFS: write_super() at %lu, clean=%d\n", get_seconds(), clean); |
67 | } | 67 | } |
68 | 68 | ||
69 | static kmem_cache_t * affs_inode_cachep; | 69 | static struct kmem_cache * affs_inode_cachep; |
70 | 70 | ||
71 | static struct inode *affs_alloc_inode(struct super_block *sb) | 71 | static struct inode *affs_alloc_inode(struct super_block *sb) |
72 | { | 72 | { |
73 | struct affs_inode_info *ei; | 73 | struct affs_inode_info *ei; |
74 | ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, SLAB_KERNEL); | 74 | ei = (struct affs_inode_info *)kmem_cache_alloc(affs_inode_cachep, GFP_KERNEL); |
75 | if (!ei) | 75 | if (!ei) |
76 | return NULL; | 76 | return NULL; |
77 | ei->vfs_inode.i_version = 1; | 77 | ei->vfs_inode.i_version = 1; |
@@ -83,7 +83,7 @@ static void affs_destroy_inode(struct inode *inode) | |||
83 | kmem_cache_free(affs_inode_cachep, AFFS_I(inode)); | 83 | kmem_cache_free(affs_inode_cachep, AFFS_I(inode)); |
84 | } | 84 | } |
85 | 85 | ||
86 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 86 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
87 | { | 87 | { |
88 | struct affs_inode_info *ei = (struct affs_inode_info *) foo; | 88 | struct affs_inode_info *ei = (struct affs_inode_info *) foo; |
89 | 89 | ||
diff --git a/fs/afs/kafsasyncd.c b/fs/afs/kafsasyncd.c index f09a794f248e..615df2407cb2 100644 --- a/fs/afs/kafsasyncd.c +++ b/fs/afs/kafsasyncd.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/completion.h> | 22 | #include <linux/completion.h> |
23 | #include <linux/freezer.h> | ||
23 | #include "cell.h" | 24 | #include "cell.h" |
24 | #include "server.h" | 25 | #include "server.h" |
25 | #include "volume.h" | 26 | #include "volume.h" |
diff --git a/fs/afs/kafstimod.c b/fs/afs/kafstimod.c index 65bc05ab8182..694344e4d3c7 100644 --- a/fs/afs/kafstimod.c +++ b/fs/afs/kafstimod.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/completion.h> | 15 | #include <linux/completion.h> |
16 | #include <linux/freezer.h> | ||
16 | #include "cell.h" | 17 | #include "cell.h" |
17 | #include "volume.h" | 18 | #include "volume.h" |
18 | #include "kafstimod.h" | 19 | #include "kafstimod.h" |
diff --git a/fs/afs/server.c b/fs/afs/server.c index 22afaae1a4ce..44aff81dc6a7 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
@@ -55,13 +55,12 @@ int afs_server_lookup(struct afs_cell *cell, const struct in_addr *addr, | |||
55 | _enter("%p,%08x,", cell, ntohl(addr->s_addr)); | 55 | _enter("%p,%08x,", cell, ntohl(addr->s_addr)); |
56 | 56 | ||
57 | /* allocate and initialise a server record */ | 57 | /* allocate and initialise a server record */ |
58 | server = kmalloc(sizeof(struct afs_server), GFP_KERNEL); | 58 | server = kzalloc(sizeof(struct afs_server), GFP_KERNEL); |
59 | if (!server) { | 59 | if (!server) { |
60 | _leave(" = -ENOMEM"); | 60 | _leave(" = -ENOMEM"); |
61 | return -ENOMEM; | 61 | return -ENOMEM; |
62 | } | 62 | } |
63 | 63 | ||
64 | memset(server, 0, sizeof(struct afs_server)); | ||
65 | atomic_set(&server->usage, 1); | 64 | atomic_set(&server->usage, 1); |
66 | 65 | ||
67 | INIT_LIST_HEAD(&server->link); | 66 | INIT_LIST_HEAD(&server->link); |
diff --git a/fs/afs/super.c b/fs/afs/super.c index 67d1f5c819ec..18d9b77ba40f 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -35,7 +35,7 @@ struct afs_mount_params { | |||
35 | struct afs_volume *volume; | 35 | struct afs_volume *volume; |
36 | }; | 36 | }; |
37 | 37 | ||
38 | static void afs_i_init_once(void *foo, kmem_cache_t *cachep, | 38 | static void afs_i_init_once(void *foo, struct kmem_cache *cachep, |
39 | unsigned long flags); | 39 | unsigned long flags); |
40 | 40 | ||
41 | static int afs_get_sb(struct file_system_type *fs_type, | 41 | static int afs_get_sb(struct file_system_type *fs_type, |
@@ -65,7 +65,7 @@ static struct super_operations afs_super_ops = { | |||
65 | .put_super = afs_put_super, | 65 | .put_super = afs_put_super, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static kmem_cache_t *afs_inode_cachep; | 68 | static struct kmem_cache *afs_inode_cachep; |
69 | static atomic_t afs_count_active_inodes; | 69 | static atomic_t afs_count_active_inodes; |
70 | 70 | ||
71 | /*****************************************************************************/ | 71 | /*****************************************************************************/ |
@@ -242,14 +242,12 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent) | |||
242 | kenter(""); | 242 | kenter(""); |
243 | 243 | ||
244 | /* allocate a superblock info record */ | 244 | /* allocate a superblock info record */ |
245 | as = kmalloc(sizeof(struct afs_super_info), GFP_KERNEL); | 245 | as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); |
246 | if (!as) { | 246 | if (!as) { |
247 | _leave(" = -ENOMEM"); | 247 | _leave(" = -ENOMEM"); |
248 | return -ENOMEM; | 248 | return -ENOMEM; |
249 | } | 249 | } |
250 | 250 | ||
251 | memset(as, 0, sizeof(struct afs_super_info)); | ||
252 | |||
253 | afs_get_volume(params->volume); | 251 | afs_get_volume(params->volume); |
254 | as->volume = params->volume; | 252 | as->volume = params->volume; |
255 | 253 | ||
@@ -384,7 +382,7 @@ static void afs_put_super(struct super_block *sb) | |||
384 | /* | 382 | /* |
385 | * initialise an inode cache slab element prior to any use | 383 | * initialise an inode cache slab element prior to any use |
386 | */ | 384 | */ |
387 | static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, | 385 | static void afs_i_init_once(void *_vnode, struct kmem_cache *cachep, |
388 | unsigned long flags) | 386 | unsigned long flags) |
389 | { | 387 | { |
390 | struct afs_vnode *vnode = (struct afs_vnode *) _vnode; | 388 | struct afs_vnode *vnode = (struct afs_vnode *) _vnode; |
@@ -412,7 +410,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb) | |||
412 | struct afs_vnode *vnode; | 410 | struct afs_vnode *vnode; |
413 | 411 | ||
414 | vnode = (struct afs_vnode *) | 412 | vnode = (struct afs_vnode *) |
415 | kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL); | 413 | kmem_cache_alloc(afs_inode_cachep, GFP_KERNEL); |
416 | if (!vnode) | 414 | if (!vnode) |
417 | return NULL; | 415 | return NULL; |
418 | 416 | ||
@@ -47,19 +47,19 @@ unsigned long aio_nr; /* current system wide number of aio requests */ | |||
47 | unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */ | 47 | unsigned long aio_max_nr = 0x10000; /* system wide maximum number of aio requests */ |
48 | /*----end sysctl variables---*/ | 48 | /*----end sysctl variables---*/ |
49 | 49 | ||
50 | static kmem_cache_t *kiocb_cachep; | 50 | static struct kmem_cache *kiocb_cachep; |
51 | static kmem_cache_t *kioctx_cachep; | 51 | static struct kmem_cache *kioctx_cachep; |
52 | 52 | ||
53 | static struct workqueue_struct *aio_wq; | 53 | static struct workqueue_struct *aio_wq; |
54 | 54 | ||
55 | /* Used for rare fput completion. */ | 55 | /* Used for rare fput completion. */ |
56 | static void aio_fput_routine(void *); | 56 | static void aio_fput_routine(struct work_struct *); |
57 | static DECLARE_WORK(fput_work, aio_fput_routine, NULL); | 57 | static DECLARE_WORK(fput_work, aio_fput_routine); |
58 | 58 | ||
59 | static DEFINE_SPINLOCK(fput_lock); | 59 | static DEFINE_SPINLOCK(fput_lock); |
60 | static LIST_HEAD(fput_head); | 60 | static LIST_HEAD(fput_head); |
61 | 61 | ||
62 | static void aio_kick_handler(void *); | 62 | static void aio_kick_handler(struct work_struct *); |
63 | static void aio_queue_work(struct kioctx *); | 63 | static void aio_queue_work(struct kioctx *); |
64 | 64 | ||
65 | /* aio_setup | 65 | /* aio_setup |
@@ -227,7 +227,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) | |||
227 | 227 | ||
228 | INIT_LIST_HEAD(&ctx->active_reqs); | 228 | INIT_LIST_HEAD(&ctx->active_reqs); |
229 | INIT_LIST_HEAD(&ctx->run_list); | 229 | INIT_LIST_HEAD(&ctx->run_list); |
230 | INIT_WORK(&ctx->wq, aio_kick_handler, ctx); | 230 | INIT_DELAYED_WORK(&ctx->wq, aio_kick_handler); |
231 | 231 | ||
232 | if (aio_setup_ring(ctx) < 0) | 232 | if (aio_setup_ring(ctx) < 0) |
233 | goto out_freectx; | 233 | goto out_freectx; |
@@ -367,8 +367,7 @@ void fastcall __put_ioctx(struct kioctx *ctx) | |||
367 | { | 367 | { |
368 | unsigned nr_events = ctx->max_reqs; | 368 | unsigned nr_events = ctx->max_reqs; |
369 | 369 | ||
370 | if (unlikely(ctx->reqs_active)) | 370 | BUG_ON(ctx->reqs_active); |
371 | BUG(); | ||
372 | 371 | ||
373 | cancel_delayed_work(&ctx->wq); | 372 | cancel_delayed_work(&ctx->wq); |
374 | flush_workqueue(aio_wq); | 373 | flush_workqueue(aio_wq); |
@@ -470,7 +469,7 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) | |||
470 | wake_up(&ctx->wait); | 469 | wake_up(&ctx->wait); |
471 | } | 470 | } |
472 | 471 | ||
473 | static void aio_fput_routine(void *data) | 472 | static void aio_fput_routine(struct work_struct *data) |
474 | { | 473 | { |
475 | spin_lock_irq(&fput_lock); | 474 | spin_lock_irq(&fput_lock); |
476 | while (likely(!list_empty(&fput_head))) { | 475 | while (likely(!list_empty(&fput_head))) { |
@@ -505,8 +504,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) | |||
505 | assert_spin_locked(&ctx->ctx_lock); | 504 | assert_spin_locked(&ctx->ctx_lock); |
506 | 505 | ||
507 | req->ki_users --; | 506 | req->ki_users --; |
508 | if (unlikely(req->ki_users < 0)) | 507 | BUG_ON(req->ki_users < 0); |
509 | BUG(); | ||
510 | if (likely(req->ki_users)) | 508 | if (likely(req->ki_users)) |
511 | return 0; | 509 | return 0; |
512 | list_del(&req->ki_list); /* remove from active_reqs */ | 510 | list_del(&req->ki_list); /* remove from active_reqs */ |
@@ -668,17 +666,6 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) | |||
668 | ssize_t (*retry)(struct kiocb *); | 666 | ssize_t (*retry)(struct kiocb *); |
669 | ssize_t ret; | 667 | ssize_t ret; |
670 | 668 | ||
671 | if (iocb->ki_retried++ > 1024*1024) { | ||
672 | printk("Maximal retry count. Bytes done %Zd\n", | ||
673 | iocb->ki_nbytes - iocb->ki_left); | ||
674 | return -EAGAIN; | ||
675 | } | ||
676 | |||
677 | if (!(iocb->ki_retried & 0xff)) { | ||
678 | pr_debug("%ld retry: %zd of %zd\n", iocb->ki_retried, | ||
679 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); | ||
680 | } | ||
681 | |||
682 | if (!(retry = iocb->ki_retry)) { | 669 | if (!(retry = iocb->ki_retry)) { |
683 | printk("aio_run_iocb: iocb->ki_retry = NULL\n"); | 670 | printk("aio_run_iocb: iocb->ki_retry = NULL\n"); |
684 | return 0; | 671 | return 0; |
@@ -859,9 +846,9 @@ static inline void aio_run_all_iocbs(struct kioctx *ctx) | |||
859 | * space. | 846 | * space. |
860 | * Run on aiod's context. | 847 | * Run on aiod's context. |
861 | */ | 848 | */ |
862 | static void aio_kick_handler(void *data) | 849 | static void aio_kick_handler(struct work_struct *work) |
863 | { | 850 | { |
864 | struct kioctx *ctx = data; | 851 | struct kioctx *ctx = container_of(work, struct kioctx, wq.work); |
865 | mm_segment_t oldfs = get_fs(); | 852 | mm_segment_t oldfs = get_fs(); |
866 | int requeue; | 853 | int requeue; |
867 | 854 | ||
@@ -876,7 +863,7 @@ static void aio_kick_handler(void *data) | |||
876 | * we're in a worker thread already, don't use queue_delayed_work, | 863 | * we're in a worker thread already, don't use queue_delayed_work, |
877 | */ | 864 | */ |
878 | if (requeue) | 865 | if (requeue) |
879 | queue_work(aio_wq, &ctx->wq); | 866 | queue_delayed_work(aio_wq, &ctx->wq, 0); |
880 | } | 867 | } |
881 | 868 | ||
882 | 869 | ||
@@ -1007,9 +994,6 @@ int fastcall aio_complete(struct kiocb *iocb, long res, long res2) | |||
1007 | kunmap_atomic(ring, KM_IRQ1); | 994 | kunmap_atomic(ring, KM_IRQ1); |
1008 | 995 | ||
1009 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); | 996 | pr_debug("added to ring %p at [%lu]\n", iocb, tail); |
1010 | |||
1011 | pr_debug("%ld retries: %zd of %zd\n", iocb->ki_retried, | ||
1012 | iocb->ki_nbytes - iocb->ki_left, iocb->ki_nbytes); | ||
1013 | put_rq: | 997 | put_rq: |
1014 | /* everything turned out well, dispose of the aiocb. */ | 998 | /* everything turned out well, dispose of the aiocb. */ |
1015 | ret = __aio_put_req(ctx, iocb); | 999 | ret = __aio_put_req(ctx, iocb); |
@@ -1415,7 +1399,6 @@ static ssize_t aio_setup_single_vector(struct kiocb *kiocb) | |||
1415 | kiocb->ki_iovec->iov_len = kiocb->ki_left; | 1399 | kiocb->ki_iovec->iov_len = kiocb->ki_left; |
1416 | kiocb->ki_nr_segs = 1; | 1400 | kiocb->ki_nr_segs = 1; |
1417 | kiocb->ki_cur_seg = 0; | 1401 | kiocb->ki_cur_seg = 0; |
1418 | kiocb->ki_nbytes = kiocb->ki_left; | ||
1419 | return 0; | 1402 | return 0; |
1420 | } | 1403 | } |
1421 | 1404 | ||
@@ -1593,7 +1576,6 @@ int fastcall io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1593 | req->ki_opcode = iocb->aio_lio_opcode; | 1576 | req->ki_opcode = iocb->aio_lio_opcode; |
1594 | init_waitqueue_func_entry(&req->ki_wait, aio_wake_function); | 1577 | init_waitqueue_func_entry(&req->ki_wait, aio_wake_function); |
1595 | INIT_LIST_HEAD(&req->ki_wait.task_list); | 1578 | INIT_LIST_HEAD(&req->ki_wait.task_list); |
1596 | req->ki_retried = 0; | ||
1597 | 1579 | ||
1598 | ret = aio_setup_iocb(req); | 1580 | ret = aio_setup_iocb(req); |
1599 | 1581 | ||
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index 54c518c89e4c..f968d1342808 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c | |||
@@ -25,6 +25,15 @@ void autofs_kill_sb(struct super_block *sb) | |||
25 | struct autofs_sb_info *sbi = autofs_sbi(sb); | 25 | struct autofs_sb_info *sbi = autofs_sbi(sb); |
26 | unsigned int n; | 26 | unsigned int n; |
27 | 27 | ||
28 | /* | ||
29 | * In the event of a failure in get_sb_nodev the superblock | ||
30 | * info is not present so nothing else has been setup, so | ||
31 | * just call kill_anon_super when we are called from | ||
32 | * deactivate_super. | ||
33 | */ | ||
34 | if (!sbi) | ||
35 | goto out_kill_sb; | ||
36 | |||
28 | if ( !sbi->catatonic ) | 37 | if ( !sbi->catatonic ) |
29 | autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ | 38 | autofs_catatonic_mode(sbi); /* Free wait queues, close pipe */ |
30 | 39 | ||
@@ -36,6 +45,7 @@ void autofs_kill_sb(struct super_block *sb) | |||
36 | 45 | ||
37 | kfree(sb->s_fs_info); | 46 | kfree(sb->s_fs_info); |
38 | 47 | ||
48 | out_kill_sb: | ||
39 | DPRINTK(("autofs: shutting down\n")); | 49 | DPRINTK(("autofs: shutting down\n")); |
40 | kill_anon_super(sb); | 50 | kill_anon_super(sb); |
41 | } | 51 | } |
@@ -136,7 +146,8 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) | |||
136 | 146 | ||
137 | s->s_fs_info = sbi; | 147 | s->s_fs_info = sbi; |
138 | sbi->magic = AUTOFS_SBI_MAGIC; | 148 | sbi->magic = AUTOFS_SBI_MAGIC; |
139 | sbi->catatonic = 0; | 149 | sbi->pipe = NULL; |
150 | sbi->catatonic = 1; | ||
140 | sbi->exp_timeout = 0; | 151 | sbi->exp_timeout = 0; |
141 | sbi->oz_pgrp = process_group(current); | 152 | sbi->oz_pgrp = process_group(current); |
142 | autofs_initialize_hash(&sbi->dirhash); | 153 | autofs_initialize_hash(&sbi->dirhash); |
@@ -180,6 +191,7 @@ int autofs_fill_super(struct super_block *s, void *data, int silent) | |||
180 | if ( !pipe->f_op || !pipe->f_op->write ) | 191 | if ( !pipe->f_op || !pipe->f_op->write ) |
181 | goto fail_fput; | 192 | goto fail_fput; |
182 | sbi->pipe = pipe; | 193 | sbi->pipe = pipe; |
194 | sbi->catatonic = 0; | ||
183 | 195 | ||
184 | /* | 196 | /* |
185 | * Success! Install the root dentry now to indicate completion. | 197 | * Success! Install the root dentry now to indicate completion. |
@@ -198,6 +210,7 @@ fail_iput: | |||
198 | iput(root_inode); | 210 | iput(root_inode); |
199 | fail_free: | 211 | fail_free: |
200 | kfree(sbi); | 212 | kfree(sbi); |
213 | s->s_fs_info = NULL; | ||
201 | fail_unlock: | 214 | fail_unlock: |
202 | return -EINVAL; | 215 | return -EINVAL; |
203 | } | 216 | } |
diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c index 633f628005b4..19a9cafb5ddf 100644 --- a/fs/autofs/waitq.c +++ b/fs/autofs/waitq.c | |||
@@ -41,6 +41,7 @@ void autofs_catatonic_mode(struct autofs_sb_info *sbi) | |||
41 | wq = nwq; | 41 | wq = nwq; |
42 | } | 42 | } |
43 | fput(sbi->pipe); /* Close the pipe */ | 43 | fput(sbi->pipe); /* Close the pipe */ |
44 | sbi->pipe = NULL; | ||
44 | autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */ | 45 | autofs_hash_dputall(&sbi->dirhash); /* Remove all dentry pointers */ |
45 | } | 46 | } |
46 | 47 | ||
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 51fd8595bf85..9c48250fd726 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -99,6 +99,9 @@ static void autofs4_force_release(struct autofs_sb_info *sbi) | |||
99 | struct dentry *this_parent = sbi->sb->s_root; | 99 | struct dentry *this_parent = sbi->sb->s_root; |
100 | struct list_head *next; | 100 | struct list_head *next; |
101 | 101 | ||
102 | if (!sbi->sb->s_root) | ||
103 | return; | ||
104 | |||
102 | spin_lock(&dcache_lock); | 105 | spin_lock(&dcache_lock); |
103 | repeat: | 106 | repeat: |
104 | next = this_parent->d_subdirs.next; | 107 | next = this_parent->d_subdirs.next; |
@@ -146,6 +149,15 @@ void autofs4_kill_sb(struct super_block *sb) | |||
146 | { | 149 | { |
147 | struct autofs_sb_info *sbi = autofs4_sbi(sb); | 150 | struct autofs_sb_info *sbi = autofs4_sbi(sb); |
148 | 151 | ||
152 | /* | ||
153 | * In the event of a failure in get_sb_nodev the superblock | ||
154 | * info is not present so nothing else has been setup, so | ||
155 | * just call kill_anon_super when we are called from | ||
156 | * deactivate_super. | ||
157 | */ | ||
158 | if (!sbi) | ||
159 | goto out_kill_sb; | ||
160 | |||
149 | sb->s_fs_info = NULL; | 161 | sb->s_fs_info = NULL; |
150 | 162 | ||
151 | if ( !sbi->catatonic ) | 163 | if ( !sbi->catatonic ) |
@@ -156,6 +168,7 @@ void autofs4_kill_sb(struct super_block *sb) | |||
156 | 168 | ||
157 | kfree(sbi); | 169 | kfree(sbi); |
158 | 170 | ||
171 | out_kill_sb: | ||
159 | DPRINTK("shutting down"); | 172 | DPRINTK("shutting down"); |
160 | kill_anon_super(sb); | 173 | kill_anon_super(sb); |
161 | } | 174 | } |
@@ -310,7 +323,8 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
310 | s->s_fs_info = sbi; | 323 | s->s_fs_info = sbi; |
311 | sbi->magic = AUTOFS_SBI_MAGIC; | 324 | sbi->magic = AUTOFS_SBI_MAGIC; |
312 | sbi->pipefd = -1; | 325 | sbi->pipefd = -1; |
313 | sbi->catatonic = 0; | 326 | sbi->pipe = NULL; |
327 | sbi->catatonic = 1; | ||
314 | sbi->exp_timeout = 0; | 328 | sbi->exp_timeout = 0; |
315 | sbi->oz_pgrp = process_group(current); | 329 | sbi->oz_pgrp = process_group(current); |
316 | sbi->sb = s; | 330 | sbi->sb = s; |
@@ -388,6 +402,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
388 | goto fail_fput; | 402 | goto fail_fput; |
389 | sbi->pipe = pipe; | 403 | sbi->pipe = pipe; |
390 | sbi->pipefd = pipefd; | 404 | sbi->pipefd = pipefd; |
405 | sbi->catatonic = 0; | ||
391 | 406 | ||
392 | /* | 407 | /* |
393 | * Success! Install the root dentry now to indicate completion. | 408 | * Success! Install the root dentry now to indicate completion. |
@@ -412,6 +427,7 @@ fail_ino: | |||
412 | kfree(ino); | 427 | kfree(ino); |
413 | fail_free: | 428 | fail_free: |
414 | kfree(sbi); | 429 | kfree(sbi); |
430 | s->s_fs_info = NULL; | ||
415 | fail_unlock: | 431 | fail_unlock: |
416 | return -EINVAL; | 432 | return -EINVAL; |
417 | } | 433 | } |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index c0a6c8d445c7..1e4a539f4417 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -41,10 +41,8 @@ void autofs4_catatonic_mode(struct autofs_sb_info *sbi) | |||
41 | wake_up_interruptible(&wq->queue); | 41 | wake_up_interruptible(&wq->queue); |
42 | wq = nwq; | 42 | wq = nwq; |
43 | } | 43 | } |
44 | if (sbi->pipe) { | 44 | fput(sbi->pipe); /* Close the pipe */ |
45 | fput(sbi->pipe); /* Close the pipe */ | 45 | sbi->pipe = NULL; |
46 | sbi->pipe = NULL; | ||
47 | } | ||
48 | } | 46 | } |
49 | 47 | ||
50 | static int autofs4_write(struct file *file, const void *addr, int bytes) | 48 | static int autofs4_write(struct file *file, const void *addr, int bytes) |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 07f7144f0e2e..bce402eee554 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -61,7 +61,7 @@ static const struct super_operations befs_sops = { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | /* slab cache for befs_inode_info objects */ | 63 | /* slab cache for befs_inode_info objects */ |
64 | static kmem_cache_t *befs_inode_cachep; | 64 | static struct kmem_cache *befs_inode_cachep; |
65 | 65 | ||
66 | static const struct file_operations befs_dir_operations = { | 66 | static const struct file_operations befs_dir_operations = { |
67 | .read = generic_read_dir, | 67 | .read = generic_read_dir, |
@@ -277,7 +277,7 @@ befs_alloc_inode(struct super_block *sb) | |||
277 | { | 277 | { |
278 | struct befs_inode_info *bi; | 278 | struct befs_inode_info *bi; |
279 | bi = (struct befs_inode_info *)kmem_cache_alloc(befs_inode_cachep, | 279 | bi = (struct befs_inode_info *)kmem_cache_alloc(befs_inode_cachep, |
280 | SLAB_KERNEL); | 280 | GFP_KERNEL); |
281 | if (!bi) | 281 | if (!bi) |
282 | return NULL; | 282 | return NULL; |
283 | return &bi->vfs_inode; | 283 | return &bi->vfs_inode; |
@@ -289,7 +289,7 @@ befs_destroy_inode(struct inode *inode) | |||
289 | kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); | 289 | kmem_cache_free(befs_inode_cachep, BEFS_I(inode)); |
290 | } | 290 | } |
291 | 291 | ||
292 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 292 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
293 | { | 293 | { |
294 | struct befs_inode_info *bi = (struct befs_inode_info *) foo; | 294 | struct befs_inode_info *bi = (struct befs_inode_info *) foo; |
295 | 295 | ||
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index ed27ffb3459e..eac175ed9f44 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c | |||
@@ -228,12 +228,12 @@ static void bfs_write_super(struct super_block *s) | |||
228 | unlock_kernel(); | 228 | unlock_kernel(); |
229 | } | 229 | } |
230 | 230 | ||
231 | static kmem_cache_t * bfs_inode_cachep; | 231 | static struct kmem_cache * bfs_inode_cachep; |
232 | 232 | ||
233 | static struct inode *bfs_alloc_inode(struct super_block *sb) | 233 | static struct inode *bfs_alloc_inode(struct super_block *sb) |
234 | { | 234 | { |
235 | struct bfs_inode_info *bi; | 235 | struct bfs_inode_info *bi; |
236 | bi = kmem_cache_alloc(bfs_inode_cachep, SLAB_KERNEL); | 236 | bi = kmem_cache_alloc(bfs_inode_cachep, GFP_KERNEL); |
237 | if (!bi) | 237 | if (!bi) |
238 | return NULL; | 238 | return NULL; |
239 | return &bi->vfs_inode; | 239 | return &bi->vfs_inode; |
@@ -244,7 +244,7 @@ static void bfs_destroy_inode(struct inode *inode) | |||
244 | kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); | 244 | kmem_cache_free(bfs_inode_cachep, BFS_I(inode)); |
245 | } | 245 | } |
246 | 246 | ||
247 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 247 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
248 | { | 248 | { |
249 | struct bfs_inode_info *bi = foo; | 249 | struct bfs_inode_info *bi = foo; |
250 | 250 | ||
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 79b05a1a4365..be5869d34999 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -47,10 +47,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs); | |||
47 | static int load_elf_library(struct file *); | 47 | static int load_elf_library(struct file *); |
48 | static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); | 48 | static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); |
49 | 49 | ||
50 | #ifndef elf_addr_t | ||
51 | #define elf_addr_t unsigned long | ||
52 | #endif | ||
53 | |||
54 | /* | 50 | /* |
55 | * If we don't support core dumping, then supply a NULL so we | 51 | * If we don't support core dumping, then supply a NULL so we |
56 | * don't even try. | 52 | * don't even try. |
@@ -243,8 +239,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
243 | if (interp_aout) { | 239 | if (interp_aout) { |
244 | argv = sp + 2; | 240 | argv = sp + 2; |
245 | envp = argv + argc + 1; | 241 | envp = argv + argc + 1; |
246 | __put_user((elf_addr_t)(unsigned long)argv, sp++); | 242 | if (__put_user((elf_addr_t)(unsigned long)argv, sp++) || |
247 | __put_user((elf_addr_t)(unsigned long)envp, sp++); | 243 | __put_user((elf_addr_t)(unsigned long)envp, sp++)) |
244 | return -EFAULT; | ||
248 | } else { | 245 | } else { |
249 | argv = sp; | 246 | argv = sp; |
250 | envp = argv + argc + 1; | 247 | envp = argv + argc + 1; |
@@ -254,7 +251,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
254 | p = current->mm->arg_end = current->mm->arg_start; | 251 | p = current->mm->arg_end = current->mm->arg_start; |
255 | while (argc-- > 0) { | 252 | while (argc-- > 0) { |
256 | size_t len; | 253 | size_t len; |
257 | __put_user((elf_addr_t)p, argv++); | 254 | if (__put_user((elf_addr_t)p, argv++)) |
255 | return -EFAULT; | ||
258 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); | 256 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); |
259 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) | 257 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) |
260 | return 0; | 258 | return 0; |
@@ -265,7 +263,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
265 | current->mm->arg_end = current->mm->env_start = p; | 263 | current->mm->arg_end = current->mm->env_start = p; |
266 | while (envc-- > 0) { | 264 | while (envc-- > 0) { |
267 | size_t len; | 265 | size_t len; |
268 | __put_user((elf_addr_t)p, envp++); | 266 | if (__put_user((elf_addr_t)p, envp++)) |
267 | return -EFAULT; | ||
269 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); | 268 | len = strnlen_user((void __user *)p, PAGE_SIZE*MAX_ARG_PAGES); |
270 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) | 269 | if (!len || len > PAGE_SIZE*MAX_ARG_PAGES) |
271 | return 0; | 270 | return 0; |
@@ -545,7 +544,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
545 | unsigned long reloc_func_desc = 0; | 544 | unsigned long reloc_func_desc = 0; |
546 | char passed_fileno[6]; | 545 | char passed_fileno[6]; |
547 | struct files_struct *files; | 546 | struct files_struct *files; |
548 | int have_pt_gnu_stack, executable_stack = EXSTACK_DEFAULT; | 547 | int executable_stack = EXSTACK_DEFAULT; |
549 | unsigned long def_flags = 0; | 548 | unsigned long def_flags = 0; |
550 | struct { | 549 | struct { |
551 | struct elfhdr elf_ex; | 550 | struct elfhdr elf_ex; |
@@ -708,7 +707,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
708 | executable_stack = EXSTACK_DISABLE_X; | 707 | executable_stack = EXSTACK_DISABLE_X; |
709 | break; | 708 | break; |
710 | } | 709 | } |
711 | have_pt_gnu_stack = (i < loc->elf_ex.e_phnum); | ||
712 | 710 | ||
713 | /* Some simple consistency checks for the interpreter */ | 711 | /* Some simple consistency checks for the interpreter */ |
714 | if (elf_interpreter) { | 712 | if (elf_interpreter) { |
@@ -856,7 +854,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
856 | * default mmap base, as well as whatever program they | 854 | * default mmap base, as well as whatever program they |
857 | * might try to exec. This is because the brk will | 855 | * might try to exec. This is because the brk will |
858 | * follow the loader, and is not movable. */ | 856 | * follow the loader, and is not movable. */ |
859 | load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); | 857 | if (current->flags & PF_RANDOMIZE) |
858 | load_bias = randomize_range(0x10000, | ||
859 | ELF_ET_DYN_BASE, | ||
860 | 0); | ||
861 | else | ||
862 | load_bias = ELF_ET_DYN_BASE; | ||
863 | load_bias = ELF_PAGESTART(load_bias - vaddr); | ||
860 | } | 864 | } |
861 | 865 | ||
862 | error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, | 866 | error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, |
@@ -1582,6 +1586,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1582 | 1586 | ||
1583 | sz += thread_status_size; | 1587 | sz += thread_status_size; |
1584 | 1588 | ||
1589 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | ||
1590 | sz += ELF_CORE_EXTRA_NOTES_SIZE; | ||
1591 | #endif | ||
1592 | |||
1585 | fill_elf_note_phdr(&phdr, sz, offset); | 1593 | fill_elf_note_phdr(&phdr, sz, offset); |
1586 | offset += sz; | 1594 | offset += sz; |
1587 | DUMP_WRITE(&phdr, sizeof(phdr)); | 1595 | DUMP_WRITE(&phdr, sizeof(phdr)); |
@@ -1622,6 +1630,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1622 | if (!writenote(notes + i, file, &foffset)) | 1630 | if (!writenote(notes + i, file, &foffset)) |
1623 | goto end_coredump; | 1631 | goto end_coredump; |
1624 | 1632 | ||
1633 | #ifdef ELF_CORE_WRITE_EXTRA_NOTES | ||
1634 | ELF_CORE_WRITE_EXTRA_NOTES; | ||
1635 | #endif | ||
1636 | |||
1625 | /* write out the thread status notes section */ | 1637 | /* write out the thread status notes section */ |
1626 | list_for_each(t, &thread_list) { | 1638 | list_for_each(t, &thread_list) { |
1627 | struct elf_thread_status *tmp = | 1639 | struct elf_thread_status *tmp = |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index f86d5c9ce5eb..ed9a61c6beb3 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -40,9 +40,6 @@ | |||
40 | #include <asm/pgalloc.h> | 40 | #include <asm/pgalloc.h> |
41 | 41 | ||
42 | typedef char *elf_caddr_t; | 42 | typedef char *elf_caddr_t; |
43 | #ifndef elf_addr_t | ||
44 | #define elf_addr_t unsigned long | ||
45 | #endif | ||
46 | 43 | ||
47 | #if 0 | 44 | #if 0 |
48 | #define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ ) | 45 | #define kdebug(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ ) |
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #define BIO_POOL_SIZE 256 | 31 | #define BIO_POOL_SIZE 256 |
32 | 32 | ||
33 | static kmem_cache_t *bio_slab __read_mostly; | 33 | static struct kmem_cache *bio_slab __read_mostly; |
34 | 34 | ||
35 | #define BIOVEC_NR_POOLS 6 | 35 | #define BIOVEC_NR_POOLS 6 |
36 | 36 | ||
@@ -44,7 +44,7 @@ mempool_t *bio_split_pool __read_mostly; | |||
44 | struct biovec_slab { | 44 | struct biovec_slab { |
45 | int nr_vecs; | 45 | int nr_vecs; |
46 | char *name; | 46 | char *name; |
47 | kmem_cache_t *slab; | 47 | struct kmem_cache *slab; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /* | 50 | /* |
@@ -560,10 +560,8 @@ struct bio *bio_copy_user(request_queue_t *q, unsigned long uaddr, | |||
560 | break; | 560 | break; |
561 | } | 561 | } |
562 | 562 | ||
563 | if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) { | 563 | if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) |
564 | ret = -EINVAL; | ||
565 | break; | 564 | break; |
566 | } | ||
567 | 565 | ||
568 | len -= bytes; | 566 | len -= bytes; |
569 | } | 567 | } |
@@ -622,10 +620,9 @@ static struct bio *__bio_map_user_iov(request_queue_t *q, | |||
622 | 620 | ||
623 | nr_pages += end - start; | 621 | nr_pages += end - start; |
624 | /* | 622 | /* |
625 | * transfer and buffer must be aligned to at least hardsector | 623 | * buffer must be aligned to at least hardsector size for now |
626 | * size for now, in the future we can relax this restriction | ||
627 | */ | 624 | */ |
628 | if ((uaddr & queue_dma_alignment(q)) || (len & queue_dma_alignment(q))) | 625 | if (uaddr & queue_dma_alignment(q)) |
629 | return ERR_PTR(-EINVAL); | 626 | return ERR_PTR(-EINVAL); |
630 | } | 627 | } |
631 | 628 | ||
@@ -751,7 +748,6 @@ struct bio *bio_map_user_iov(request_queue_t *q, struct block_device *bdev, | |||
751 | int write_to_vm) | 748 | int write_to_vm) |
752 | { | 749 | { |
753 | struct bio *bio; | 750 | struct bio *bio; |
754 | int len = 0, i; | ||
755 | 751 | ||
756 | bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm); | 752 | bio = __bio_map_user_iov(q, bdev, iov, iov_count, write_to_vm); |
757 | 753 | ||
@@ -766,18 +762,7 @@ struct bio *bio_map_user_iov(request_queue_t *q, struct block_device *bdev, | |||
766 | */ | 762 | */ |
767 | bio_get(bio); | 763 | bio_get(bio); |
768 | 764 | ||
769 | for (i = 0; i < iov_count; i++) | 765 | return bio; |
770 | len += iov[i].iov_len; | ||
771 | |||
772 | if (bio->bi_size == len) | ||
773 | return bio; | ||
774 | |||
775 | /* | ||
776 | * don't support partial mappings | ||
777 | */ | ||
778 | bio_endio(bio, bio->bi_size, 0); | ||
779 | bio_unmap_user(bio); | ||
780 | return ERR_PTR(-EINVAL); | ||
781 | } | 766 | } |
782 | 767 | ||
783 | static void __bio_unmap_user(struct bio *bio) | 768 | static void __bio_unmap_user(struct bio *bio) |
@@ -955,16 +940,16 @@ static void bio_release_pages(struct bio *bio) | |||
955 | * run one bio_put() against the BIO. | 940 | * run one bio_put() against the BIO. |
956 | */ | 941 | */ |
957 | 942 | ||
958 | static void bio_dirty_fn(void *data); | 943 | static void bio_dirty_fn(struct work_struct *work); |
959 | 944 | ||
960 | static DECLARE_WORK(bio_dirty_work, bio_dirty_fn, NULL); | 945 | static DECLARE_WORK(bio_dirty_work, bio_dirty_fn); |
961 | static DEFINE_SPINLOCK(bio_dirty_lock); | 946 | static DEFINE_SPINLOCK(bio_dirty_lock); |
962 | static struct bio *bio_dirty_list; | 947 | static struct bio *bio_dirty_list; |
963 | 948 | ||
964 | /* | 949 | /* |
965 | * This runs in process context | 950 | * This runs in process context |
966 | */ | 951 | */ |
967 | static void bio_dirty_fn(void *data) | 952 | static void bio_dirty_fn(struct work_struct *work) |
968 | { | 953 | { |
969 | unsigned long flags; | 954 | unsigned long flags; |
970 | struct bio *bio; | 955 | struct bio *bio; |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 36c0e7af9d0f..13816b4d76f6 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -235,11 +235,11 @@ static int block_fsync(struct file *filp, struct dentry *dentry, int datasync) | |||
235 | */ | 235 | */ |
236 | 236 | ||
237 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(bdev_lock); | 237 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(bdev_lock); |
238 | static kmem_cache_t * bdev_cachep __read_mostly; | 238 | static struct kmem_cache * bdev_cachep __read_mostly; |
239 | 239 | ||
240 | static struct inode *bdev_alloc_inode(struct super_block *sb) | 240 | static struct inode *bdev_alloc_inode(struct super_block *sb) |
241 | { | 241 | { |
242 | struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, SLAB_KERNEL); | 242 | struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL); |
243 | if (!ei) | 243 | if (!ei) |
244 | return NULL; | 244 | return NULL; |
245 | return &ei->vfs_inode; | 245 | return &ei->vfs_inode; |
@@ -253,7 +253,7 @@ static void bdev_destroy_inode(struct inode *inode) | |||
253 | kmem_cache_free(bdev_cachep, bdi); | 253 | kmem_cache_free(bdev_cachep, bdi); |
254 | } | 254 | } |
255 | 255 | ||
256 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 256 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
257 | { | 257 | { |
258 | struct bdev_inode *ei = (struct bdev_inode *) foo; | 258 | struct bdev_inode *ei = (struct bdev_inode *) foo; |
259 | struct block_device *bdev = &ei->bdev; | 259 | struct block_device *bdev = &ei->bdev; |
diff --git a/fs/buffer.c b/fs/buffer.c index 35527dca1dbc..517860f2d75b 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2908,7 +2908,7 @@ asmlinkage long sys_bdflush(int func, long data) | |||
2908 | /* | 2908 | /* |
2909 | * Buffer-head allocation | 2909 | * Buffer-head allocation |
2910 | */ | 2910 | */ |
2911 | static kmem_cache_t *bh_cachep; | 2911 | static struct kmem_cache *bh_cachep; |
2912 | 2912 | ||
2913 | /* | 2913 | /* |
2914 | * Once the number of bh's in the machine exceeds this level, we start | 2914 | * Once the number of bh's in the machine exceeds this level, we start |
@@ -2961,7 +2961,7 @@ void free_buffer_head(struct buffer_head *bh) | |||
2961 | EXPORT_SYMBOL(free_buffer_head); | 2961 | EXPORT_SYMBOL(free_buffer_head); |
2962 | 2962 | ||
2963 | static void | 2963 | static void |
2964 | init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) | 2964 | init_buffer_head(void *data, struct kmem_cache *cachep, unsigned long flags) |
2965 | { | 2965 | { |
2966 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 2966 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == |
2967 | SLAB_CTOR_CONSTRUCTOR) { | 2967 | SLAB_CTOR_CONSTRUCTOR) { |
@@ -2972,7 +2972,6 @@ init_buffer_head(void *data, kmem_cache_t *cachep, unsigned long flags) | |||
2972 | } | 2972 | } |
2973 | } | 2973 | } |
2974 | 2974 | ||
2975 | #ifdef CONFIG_HOTPLUG_CPU | ||
2976 | static void buffer_exit_cpu(int cpu) | 2975 | static void buffer_exit_cpu(int cpu) |
2977 | { | 2976 | { |
2978 | int i; | 2977 | int i; |
@@ -2994,7 +2993,6 @@ static int buffer_cpu_notify(struct notifier_block *self, | |||
2994 | buffer_exit_cpu((unsigned long)hcpu); | 2993 | buffer_exit_cpu((unsigned long)hcpu); |
2995 | return NOTIFY_OK; | 2994 | return NOTIFY_OK; |
2996 | } | 2995 | } |
2997 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
2998 | 2996 | ||
2999 | void __init buffer_init(void) | 2997 | void __init buffer_init(void) |
3000 | { | 2998 | { |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 84976cdbe713..71bc87a37fc1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mempool.h> | 34 | #include <linux/mempool.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/freezer.h> | ||
37 | #include "cifsfs.h" | 38 | #include "cifsfs.h" |
38 | #include "cifspdu.h" | 39 | #include "cifspdu.h" |
39 | #define DECLARE_GLOBALS_HERE | 40 | #define DECLARE_GLOBALS_HERE |
@@ -81,7 +82,7 @@ extern mempool_t *cifs_sm_req_poolp; | |||
81 | extern mempool_t *cifs_req_poolp; | 82 | extern mempool_t *cifs_req_poolp; |
82 | extern mempool_t *cifs_mid_poolp; | 83 | extern mempool_t *cifs_mid_poolp; |
83 | 84 | ||
84 | extern kmem_cache_t *cifs_oplock_cachep; | 85 | extern struct kmem_cache *cifs_oplock_cachep; |
85 | 86 | ||
86 | static int | 87 | static int |
87 | cifs_read_super(struct super_block *sb, void *data, | 88 | cifs_read_super(struct super_block *sb, void *data, |
@@ -232,11 +233,11 @@ static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd) | |||
232 | return generic_permission(inode, mask, NULL); | 233 | return generic_permission(inode, mask, NULL); |
233 | } | 234 | } |
234 | 235 | ||
235 | static kmem_cache_t *cifs_inode_cachep; | 236 | static struct kmem_cache *cifs_inode_cachep; |
236 | static kmem_cache_t *cifs_req_cachep; | 237 | static struct kmem_cache *cifs_req_cachep; |
237 | static kmem_cache_t *cifs_mid_cachep; | 238 | static struct kmem_cache *cifs_mid_cachep; |
238 | kmem_cache_t *cifs_oplock_cachep; | 239 | struct kmem_cache *cifs_oplock_cachep; |
239 | static kmem_cache_t *cifs_sm_req_cachep; | 240 | static struct kmem_cache *cifs_sm_req_cachep; |
240 | mempool_t *cifs_sm_req_poolp; | 241 | mempool_t *cifs_sm_req_poolp; |
241 | mempool_t *cifs_req_poolp; | 242 | mempool_t *cifs_req_poolp; |
242 | mempool_t *cifs_mid_poolp; | 243 | mempool_t *cifs_mid_poolp; |
@@ -245,7 +246,7 @@ static struct inode * | |||
245 | cifs_alloc_inode(struct super_block *sb) | 246 | cifs_alloc_inode(struct super_block *sb) |
246 | { | 247 | { |
247 | struct cifsInodeInfo *cifs_inode; | 248 | struct cifsInodeInfo *cifs_inode; |
248 | cifs_inode = kmem_cache_alloc(cifs_inode_cachep, SLAB_KERNEL); | 249 | cifs_inode = kmem_cache_alloc(cifs_inode_cachep, GFP_KERNEL); |
249 | if (!cifs_inode) | 250 | if (!cifs_inode) |
250 | return NULL; | 251 | return NULL; |
251 | cifs_inode->cifsAttrs = 0x20; /* default */ | 252 | cifs_inode->cifsAttrs = 0x20; /* default */ |
@@ -668,7 +669,7 @@ const struct file_operations cifs_dir_ops = { | |||
668 | }; | 669 | }; |
669 | 670 | ||
670 | static void | 671 | static void |
671 | cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags) | 672 | cifs_init_once(void *inode, struct kmem_cache * cachep, unsigned long flags) |
672 | { | 673 | { |
673 | struct cifsInodeInfo *cifsi = inode; | 674 | struct cifsInodeInfo *cifsi = inode; |
674 | 675 | ||
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 71f77914ce93..2caca06b4bae 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/completion.h> | 32 | #include <linux/completion.h> |
33 | #include <linux/pagevec.h> | 33 | #include <linux/pagevec.h> |
34 | #include <linux/freezer.h> | ||
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
35 | #include <asm/processor.h> | 36 | #include <asm/processor.h> |
36 | #include "cifspdu.h" | 37 | #include "cifspdu.h" |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 7e056b9b49e8..2436ed8fc840 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -492,10 +492,14 @@ int cifs_close(struct inode *inode, struct file *file) | |||
492 | the struct would be in each open file, | 492 | the struct would be in each open file, |
493 | but this should give enough time to | 493 | but this should give enough time to |
494 | clear the socket */ | 494 | clear the socket */ |
495 | cERROR(1,("close with pending writes")); | 495 | #ifdef CONFIG_CIFS_DEBUG2 |
496 | cFYI(1,("close delay, write pending")); | ||
497 | #endif /* DEBUG2 */ | ||
496 | msleep(timeout); | 498 | msleep(timeout); |
497 | timeout *= 4; | 499 | timeout *= 4; |
498 | } | 500 | } |
501 | if(atomic_read(&pSMBFile->wrtPending)) | ||
502 | cERROR(1,("close with pending writes")); | ||
499 | rc = CIFSSMBClose(xid, pTcon, | 503 | rc = CIFSSMBClose(xid, pTcon, |
500 | pSMBFile->netfid); | 504 | pSMBFile->netfid); |
501 | } | 505 | } |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index dffe295825f4..c4fa91b8b62f 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -318,6 +318,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
318 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 318 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
319 | char *tmp_path; | 319 | char *tmp_path; |
320 | char *buf = NULL; | 320 | char *buf = NULL; |
321 | int adjustTZ = FALSE; | ||
321 | 322 | ||
322 | pTcon = cifs_sb->tcon; | 323 | pTcon = cifs_sb->tcon; |
323 | cFYI(1,("Getting info on %s", search_path)); | 324 | cFYI(1,("Getting info on %s", search_path)); |
@@ -348,6 +349,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
348 | pfindData, cifs_sb->local_nls, | 349 | pfindData, cifs_sb->local_nls, |
349 | cifs_sb->mnt_cifs_flags & | 350 | cifs_sb->mnt_cifs_flags & |
350 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 351 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
352 | adjustTZ = TRUE; | ||
351 | } | 353 | } |
352 | 354 | ||
353 | } | 355 | } |
@@ -444,6 +446,10 @@ int cifs_get_inode_info(struct inode **pinode, | |||
444 | inode->i_ctime = | 446 | inode->i_ctime = |
445 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); | 447 | cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); |
446 | cFYI(0, ("Attributes came in as 0x%x", attr)); | 448 | cFYI(0, ("Attributes came in as 0x%x", attr)); |
449 | if(adjustTZ && (pTcon->ses) && (pTcon->ses->server)) { | ||
450 | inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj; | ||
451 | inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; | ||
452 | } | ||
447 | 453 | ||
448 | /* set default mode. will override for dirs below */ | 454 | /* set default mode. will override for dirs below */ |
449 | if (atomic_read(&cifsInfo->inUse) == 0) | 455 | if (atomic_read(&cifsInfo->inUse) == 0) |
@@ -1089,8 +1095,10 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1089 | struct kstat *stat) | 1095 | struct kstat *stat) |
1090 | { | 1096 | { |
1091 | int err = cifs_revalidate(dentry); | 1097 | int err = cifs_revalidate(dentry); |
1092 | if (!err) | 1098 | if (!err) { |
1093 | generic_fillattr(dentry->d_inode, stat); | 1099 | generic_fillattr(dentry->d_inode, stat); |
1100 | stat->blksize = CIFS_MAX_MSGSIZE; | ||
1101 | } | ||
1094 | return err; | 1102 | return err; |
1095 | } | 1103 | } |
1096 | 1104 | ||
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 0bee8b7e521a..8e259969354b 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -69,17 +69,30 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, | |||
69 | rc = -EOPNOTSUPP; | 69 | rc = -EOPNOTSUPP; |
70 | } | 70 | } |
71 | 71 | ||
72 | /* if (!rc) */ | 72 | d_drop(direntry); /* force new lookup from server of target */ |
73 | { | 73 | |
74 | /* renew_parental_timestamps(old_file); | 74 | /* if source file is cached (oplocked) revalidate will not go to server |
75 | inode->i_nlink++; | 75 | until the file is closed or oplock broken so update nlinks locally */ |
76 | mark_inode_dirty(inode); | 76 | if(old_file->d_inode) { |
77 | d_instantiate(direntry, inode); */ | 77 | cifsInode = CIFS_I(old_file->d_inode); |
78 | /* BB add call to either mark inode dirty or refresh its data and timestamp to current time */ | 78 | if(rc == 0) { |
79 | old_file->d_inode->i_nlink++; | ||
80 | old_file->d_inode->i_ctime = CURRENT_TIME; | ||
81 | /* parent dir timestamps will update from srv | ||
82 | within a second, would it really be worth it | ||
83 | to set the parent dir cifs inode time to zero | ||
84 | to force revalidate (faster) for it too? */ | ||
85 | } | ||
86 | /* if not oplocked will force revalidate to get info | ||
87 | on source file from srv */ | ||
88 | cifsInode->time = 0; | ||
89 | |||
90 | /* Will update parent dir timestamps from srv within a second. | ||
91 | Would it really be worth it to set the parent dir (cifs | ||
92 | inode) time field to zero to force revalidate on parent | ||
93 | directory faster ie | ||
94 | CIFS_I(inode)->time = 0; */ | ||
79 | } | 95 | } |
80 | d_drop(direntry); /* force new lookup from server */ | ||
81 | cifsInode = CIFS_I(old_file->d_inode); | ||
82 | cifsInode->time = 0; /* will force revalidate to go get info when needed */ | ||
83 | 96 | ||
84 | cifs_hl_exit: | 97 | cifs_hl_exit: |
85 | kfree(fromName); | 98 | kfree(fromName); |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index bbc9cd34b6ea..aedf683f011f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -153,7 +153,7 @@ cifs_buf_get(void) | |||
153 | albeit slightly larger than necessary and maxbuffersize | 153 | albeit slightly larger than necessary and maxbuffersize |
154 | defaults to this and can not be bigger */ | 154 | defaults to this and can not be bigger */ |
155 | ret_buf = | 155 | ret_buf = |
156 | (struct smb_hdr *) mempool_alloc(cifs_req_poolp, SLAB_KERNEL | SLAB_NOFS); | 156 | (struct smb_hdr *) mempool_alloc(cifs_req_poolp, GFP_KERNEL | GFP_NOFS); |
157 | 157 | ||
158 | /* clear the first few header bytes */ | 158 | /* clear the first few header bytes */ |
159 | /* for most paths, more is cleared in header_assemble */ | 159 | /* for most paths, more is cleared in header_assemble */ |
@@ -192,7 +192,7 @@ cifs_small_buf_get(void) | |||
192 | albeit slightly larger than necessary and maxbuffersize | 192 | albeit slightly larger than necessary and maxbuffersize |
193 | defaults to this and can not be bigger */ | 193 | defaults to this and can not be bigger */ |
194 | ret_buf = | 194 | ret_buf = |
195 | (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, SLAB_KERNEL | SLAB_NOFS); | 195 | (struct smb_hdr *) mempool_alloc(cifs_sm_req_poolp, GFP_KERNEL | GFP_NOFS); |
196 | if (ret_buf) { | 196 | if (ret_buf) { |
197 | /* No need to clear memory here, cleared in header assemble */ | 197 | /* No need to clear memory here, cleared in header assemble */ |
198 | /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ | 198 | /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/ |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index a8a083543ba0..bbdda99dce61 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -90,7 +90,9 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, | |||
90 | } */ | 90 | } */ |
91 | /* copy user */ | 91 | /* copy user */ |
92 | if(ses->userName == NULL) { | 92 | if(ses->userName == NULL) { |
93 | /* BB what about null user mounts - check that we do this BB */ | 93 | /* null user mount */ |
94 | *bcc_ptr = 0; | ||
95 | *(bcc_ptr+1) = 0; | ||
94 | } else { /* 300 should be long enough for any conceivable user name */ | 96 | } else { /* 300 should be long enough for any conceivable user name */ |
95 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName, | 97 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName, |
96 | 300, nls_cp); | 98 | 300, nls_cp); |
@@ -98,10 +100,13 @@ static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, | |||
98 | bcc_ptr += 2 * bytes_ret; | 100 | bcc_ptr += 2 * bytes_ret; |
99 | bcc_ptr += 2; /* account for null termination */ | 101 | bcc_ptr += 2; /* account for null termination */ |
100 | /* copy domain */ | 102 | /* copy domain */ |
101 | if(ses->domainName == NULL) | 103 | if(ses->domainName == NULL) { |
102 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, | 104 | /* Sending null domain better than using a bogus domain name (as |
103 | "CIFS_LINUX_DOM", 32, nls_cp); | 105 | we did briefly in 2.6.18) since server will use its default */ |
104 | else | 106 | *bcc_ptr = 0; |
107 | *(bcc_ptr+1) = 0; | ||
108 | bytes_ret = 0; | ||
109 | } else | ||
105 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, | 110 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, |
106 | 256, nls_cp); | 111 | 256, nls_cp); |
107 | bcc_ptr += 2 * bytes_ret; | 112 | bcc_ptr += 2 * bytes_ret; |
@@ -144,13 +149,11 @@ static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, | |||
144 | 149 | ||
145 | /* copy domain */ | 150 | /* copy domain */ |
146 | 151 | ||
147 | if(ses->domainName == NULL) { | 152 | if(ses->domainName != NULL) { |
148 | strcpy(bcc_ptr, "CIFS_LINUX_DOM"); | ||
149 | bcc_ptr += 14; /* strlen(CIFS_LINUX_DOM) */ | ||
150 | } else { | ||
151 | strncpy(bcc_ptr, ses->domainName, 256); | 153 | strncpy(bcc_ptr, ses->domainName, 256); |
152 | bcc_ptr += strnlen(ses->domainName, 256); | 154 | bcc_ptr += strnlen(ses->domainName, 256); |
153 | } | 155 | } /* else we will send a null domain name |
156 | so the server will default to its own domain */ | ||
154 | *bcc_ptr = 0; | 157 | *bcc_ptr = 0; |
155 | bcc_ptr++; | 158 | bcc_ptr++; |
156 | 159 | ||
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 48d47b46b1fb..f80007eaebf4 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "cifs_debug.h" | 34 | #include "cifs_debug.h" |
35 | 35 | ||
36 | extern mempool_t *cifs_mid_poolp; | 36 | extern mempool_t *cifs_mid_poolp; |
37 | extern kmem_cache_t *cifs_oplock_cachep; | 37 | extern struct kmem_cache *cifs_oplock_cachep; |
38 | 38 | ||
39 | static struct mid_q_entry * | 39 | static struct mid_q_entry * |
40 | AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) | 40 | AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) |
@@ -51,7 +51,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, | 53 | temp = (struct mid_q_entry *) mempool_alloc(cifs_mid_poolp, |
54 | SLAB_KERNEL | SLAB_NOFS); | 54 | GFP_KERNEL | GFP_NOFS); |
55 | if (temp == NULL) | 55 | if (temp == NULL) |
56 | return temp; | 56 | return temp; |
57 | else { | 57 | else { |
@@ -118,7 +118,7 @@ AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon) | |||
118 | return NULL; | 118 | return NULL; |
119 | } | 119 | } |
120 | temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep, | 120 | temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep, |
121 | SLAB_KERNEL); | 121 | GFP_KERNEL); |
122 | if (temp == NULL) | 122 | if (temp == NULL) |
123 | return temp; | 123 | return temp; |
124 | else { | 124 | else { |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 88d123321164..b64659fa82d0 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -38,12 +38,12 @@ static void coda_clear_inode(struct inode *); | |||
38 | static void coda_put_super(struct super_block *); | 38 | static void coda_put_super(struct super_block *); |
39 | static int coda_statfs(struct dentry *dentry, struct kstatfs *buf); | 39 | static int coda_statfs(struct dentry *dentry, struct kstatfs *buf); |
40 | 40 | ||
41 | static kmem_cache_t * coda_inode_cachep; | 41 | static struct kmem_cache * coda_inode_cachep; |
42 | 42 | ||
43 | static struct inode *coda_alloc_inode(struct super_block *sb) | 43 | static struct inode *coda_alloc_inode(struct super_block *sb) |
44 | { | 44 | { |
45 | struct coda_inode_info *ei; | 45 | struct coda_inode_info *ei; |
46 | ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, SLAB_KERNEL); | 46 | ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); |
47 | if (!ei) | 47 | if (!ei) |
48 | return NULL; | 48 | return NULL; |
49 | memset(&ei->c_fid, 0, sizeof(struct CodaFid)); | 49 | memset(&ei->c_fid, 0, sizeof(struct CodaFid)); |
@@ -58,7 +58,7 @@ static void coda_destroy_inode(struct inode *inode) | |||
58 | kmem_cache_free(coda_inode_cachep, ITOC(inode)); | 58 | kmem_cache_free(coda_inode_cachep, ITOC(inode)); |
59 | } | 59 | } |
60 | 60 | ||
61 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 61 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
62 | { | 62 | { |
63 | struct coda_inode_info *ei = (struct coda_inode_info *) foo; | 63 | struct coda_inode_info *ei = (struct coda_inode_info *) foo; |
64 | 64 | ||
diff --git a/fs/compat.c b/fs/compat.c index 8d0a0018a7d2..a7e3f162fb15 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <linux/personality.h> | 45 | #include <linux/personality.h> |
46 | #include <linux/rwsem.h> | 46 | #include <linux/rwsem.h> |
47 | #include <linux/tsacct_kern.h> | 47 | #include <linux/tsacct_kern.h> |
48 | #include <linux/highmem.h> | ||
49 | #include <linux/poll.h> | ||
48 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
49 | 51 | ||
50 | #include <net/sock.h> /* siocdevprivate_ioctl */ | 52 | #include <net/sock.h> /* siocdevprivate_ioctl */ |
@@ -869,7 +871,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name, | |||
869 | 871 | ||
870 | retval = -EINVAL; | 872 | retval = -EINVAL; |
871 | 873 | ||
872 | if (type_page) { | 874 | if (type_page && data_page) { |
873 | if (!strcmp((char *)type_page, SMBFS_NAME)) { | 875 | if (!strcmp((char *)type_page, SMBFS_NAME)) { |
874 | do_smb_super_data_conv((void *)data_page); | 876 | do_smb_super_data_conv((void *)data_page); |
875 | } else if (!strcmp((char *)type_page, NCPFS_NAME)) { | 877 | } else if (!strcmp((char *)type_page, NCPFS_NAME)) { |
@@ -1142,7 +1144,9 @@ asmlinkage long compat_sys_getdents64(unsigned int fd, | |||
1142 | lastdirent = buf.previous; | 1144 | lastdirent = buf.previous; |
1143 | if (lastdirent) { | 1145 | if (lastdirent) { |
1144 | typeof(lastdirent->d_off) d_off = file->f_pos; | 1146 | typeof(lastdirent->d_off) d_off = file->f_pos; |
1145 | __put_user_unaligned(d_off, &lastdirent->d_off); | 1147 | error = -EFAULT; |
1148 | if (__put_user_unaligned(d_off, &lastdirent->d_off)) | ||
1149 | goto out_putf; | ||
1146 | error = count - buf.count; | 1150 | error = count - buf.count; |
1147 | } | 1151 | } |
1148 | 1152 | ||
@@ -1609,14 +1613,14 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | |||
1609 | nr &= ~1UL; | 1613 | nr &= ~1UL; |
1610 | while (nr) { | 1614 | while (nr) { |
1611 | unsigned long h, l; | 1615 | unsigned long h, l; |
1612 | __get_user(l, ufdset); | 1616 | if (__get_user(l, ufdset) || __get_user(h, ufdset+1)) |
1613 | __get_user(h, ufdset+1); | 1617 | return -EFAULT; |
1614 | ufdset += 2; | 1618 | ufdset += 2; |
1615 | *fdset++ = h << 32 | l; | 1619 | *fdset++ = h << 32 | l; |
1616 | nr -= 2; | 1620 | nr -= 2; |
1617 | } | 1621 | } |
1618 | if (odd) | 1622 | if (odd && __get_user(*fdset, ufdset)) |
1619 | __get_user(*fdset, ufdset); | 1623 | return -EFAULT; |
1620 | } else { | 1624 | } else { |
1621 | /* Tricky, must clear full unsigned long in the | 1625 | /* Tricky, must clear full unsigned long in the |
1622 | * kernel fdset at the end, this makes sure that | 1626 | * kernel fdset at the end, this makes sure that |
@@ -1628,14 +1632,14 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | |||
1628 | } | 1632 | } |
1629 | 1633 | ||
1630 | static | 1634 | static |
1631 | void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | 1635 | int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, |
1632 | unsigned long *fdset) | 1636 | unsigned long *fdset) |
1633 | { | 1637 | { |
1634 | unsigned long odd; | 1638 | unsigned long odd; |
1635 | nr = ROUND_UP(nr, __COMPAT_NFDBITS); | 1639 | nr = ROUND_UP(nr, __COMPAT_NFDBITS); |
1636 | 1640 | ||
1637 | if (!ufdset) | 1641 | if (!ufdset) |
1638 | return; | 1642 | return 0; |
1639 | 1643 | ||
1640 | odd = nr & 1UL; | 1644 | odd = nr & 1UL; |
1641 | nr &= ~1UL; | 1645 | nr &= ~1UL; |
@@ -1643,13 +1647,14 @@ void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | |||
1643 | unsigned long h, l; | 1647 | unsigned long h, l; |
1644 | l = *fdset++; | 1648 | l = *fdset++; |
1645 | h = l >> 32; | 1649 | h = l >> 32; |
1646 | __put_user(l, ufdset); | 1650 | if (__put_user(l, ufdset) || __put_user(h, ufdset+1)) |
1647 | __put_user(h, ufdset+1); | 1651 | return -EFAULT; |
1648 | ufdset += 2; | 1652 | ufdset += 2; |
1649 | nr -= 2; | 1653 | nr -= 2; |
1650 | } | 1654 | } |
1651 | if (odd) | 1655 | if (odd && __put_user(*fdset, ufdset)) |
1652 | __put_user(*fdset, ufdset); | 1656 | return -EFAULT; |
1657 | return 0; | ||
1653 | } | 1658 | } |
1654 | 1659 | ||
1655 | 1660 | ||
@@ -1724,10 +1729,10 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp, | |||
1724 | ret = 0; | 1729 | ret = 0; |
1725 | } | 1730 | } |
1726 | 1731 | ||
1727 | compat_set_fd_set(n, inp, fds.res_in); | 1732 | if (compat_set_fd_set(n, inp, fds.res_in) || |
1728 | compat_set_fd_set(n, outp, fds.res_out); | 1733 | compat_set_fd_set(n, outp, fds.res_out) || |
1729 | compat_set_fd_set(n, exp, fds.res_ex); | 1734 | compat_set_fd_set(n, exp, fds.res_ex)) |
1730 | 1735 | ret = -EFAULT; | |
1731 | out: | 1736 | out: |
1732 | kfree(bits); | 1737 | kfree(bits); |
1733 | out_nofds: | 1738 | out_nofds: |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index a91f2628c981..bcc3caf5d820 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -211,8 +211,10 @@ static int do_video_stillpicture(unsigned int fd, unsigned int cmd, unsigned lon | |||
211 | up_native = | 211 | up_native = |
212 | compat_alloc_user_space(sizeof(struct video_still_picture)); | 212 | compat_alloc_user_space(sizeof(struct video_still_picture)); |
213 | 213 | ||
214 | put_user(compat_ptr(fp), &up_native->iFrame); | 214 | err = put_user(compat_ptr(fp), &up_native->iFrame); |
215 | put_user(size, &up_native->size); | 215 | err |= put_user(size, &up_native->size); |
216 | if (err) | ||
217 | return -EFAULT; | ||
216 | 218 | ||
217 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); | 219 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); |
218 | 220 | ||
@@ -236,8 +238,10 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd, unsigned | |||
236 | err |= get_user(length, &up->length); | 238 | err |= get_user(length, &up->length); |
237 | 239 | ||
238 | up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); | 240 | up_native = compat_alloc_user_space(sizeof(struct video_spu_palette)); |
239 | put_user(compat_ptr(palp), &up_native->palette); | 241 | err = put_user(compat_ptr(palp), &up_native->palette); |
240 | put_user(length, &up_native->length); | 242 | err |= put_user(length, &up_native->length); |
243 | if (err) | ||
244 | return -EFAULT; | ||
241 | 245 | ||
242 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); | 246 | err = sys_ioctl(fd, cmd, (unsigned long) up_native); |
243 | 247 | ||
@@ -2043,16 +2047,19 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | |||
2043 | struct serial_struct ss; | 2047 | struct serial_struct ss; |
2044 | mm_segment_t oldseg = get_fs(); | 2048 | mm_segment_t oldseg = get_fs(); |
2045 | __u32 udata; | 2049 | __u32 udata; |
2050 | unsigned int base; | ||
2046 | 2051 | ||
2047 | if (cmd == TIOCSSERIAL) { | 2052 | if (cmd == TIOCSSERIAL) { |
2048 | if (!access_ok(VERIFY_READ, ss32, sizeof(SS32))) | 2053 | if (!access_ok(VERIFY_READ, ss32, sizeof(SS32))) |
2049 | return -EFAULT; | 2054 | return -EFAULT; |
2050 | if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base))) | 2055 | if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base))) |
2051 | return -EFAULT; | 2056 | return -EFAULT; |
2052 | __get_user(udata, &ss32->iomem_base); | 2057 | if (__get_user(udata, &ss32->iomem_base)) |
2058 | return -EFAULT; | ||
2053 | ss.iomem_base = compat_ptr(udata); | 2059 | ss.iomem_base = compat_ptr(udata); |
2054 | __get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift); | 2060 | if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) || |
2055 | __get_user(ss.port_high, &ss32->port_high); | 2061 | __get_user(ss.port_high, &ss32->port_high)) |
2062 | return -EFAULT; | ||
2056 | ss.iomap_base = 0UL; | 2063 | ss.iomap_base = 0UL; |
2057 | } | 2064 | } |
2058 | set_fs(KERNEL_DS); | 2065 | set_fs(KERNEL_DS); |
@@ -2063,12 +2070,12 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg) | |||
2063 | return -EFAULT; | 2070 | return -EFAULT; |
2064 | if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base))) | 2071 | if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base))) |
2065 | return -EFAULT; | 2072 | return -EFAULT; |
2066 | __put_user((unsigned long)ss.iomem_base >> 32 ? | 2073 | base = (unsigned long)ss.iomem_base >> 32 ? |
2067 | 0xffffffff : (unsigned)(unsigned long)ss.iomem_base, | 2074 | 0xffffffff : (unsigned)(unsigned long)ss.iomem_base; |
2068 | &ss32->iomem_base); | 2075 | if (__put_user(base, &ss32->iomem_base) || |
2069 | __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift); | 2076 | __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) || |
2070 | __put_user(ss.port_high, &ss32->port_high); | 2077 | __put_user(ss.port_high, &ss32->port_high)) |
2071 | 2078 | return -EFAULT; | |
2072 | } | 2079 | } |
2073 | return err; | 2080 | return err; |
2074 | } | 2081 | } |
@@ -2397,6 +2404,7 @@ HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc) | |||
2397 | HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) | 2404 | HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc) |
2398 | HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) | 2405 | HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc) |
2399 | HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) | 2406 | HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc) |
2407 | HANDLE_IOCTL(SIOCSIFHWBROADCAST, dev_ifsioc) | ||
2400 | 2408 | ||
2401 | /* ioctls used by appletalk ddp.c */ | 2409 | /* ioctls used by appletalk ddp.c */ |
2402 | HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) | 2410 | HANDLE_IOCTL(SIOCATALKDIFADDR, dev_ifsioc) |
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index 3f4ff7a242b9..f92cd303d2c9 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h | |||
@@ -49,7 +49,7 @@ struct configfs_dirent { | |||
49 | #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) | 49 | #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) |
50 | 50 | ||
51 | extern struct vfsmount * configfs_mount; | 51 | extern struct vfsmount * configfs_mount; |
52 | extern kmem_cache_t *configfs_dir_cachep; | 52 | extern struct kmem_cache *configfs_dir_cachep; |
53 | 53 | ||
54 | extern int configfs_is_root(struct config_item *item); | 54 | extern int configfs_is_root(struct config_item *item); |
55 | 55 | ||
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 8a3b6a1a6ad1..c398861f78a5 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -93,8 +93,8 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare | |||
93 | * | 93 | * |
94 | * called with parent inode's i_mutex held | 94 | * called with parent inode's i_mutex held |
95 | */ | 95 | */ |
96 | int configfs_dirent_exists(struct configfs_dirent *parent_sd, | 96 | static int configfs_dirent_exists(struct configfs_dirent *parent_sd, |
97 | const unsigned char *new) | 97 | const unsigned char *new) |
98 | { | 98 | { |
99 | struct configfs_dirent * sd; | 99 | struct configfs_dirent * sd; |
100 | 100 | ||
@@ -1176,8 +1176,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys) | |||
1176 | return; | 1176 | return; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); | 1179 | mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex, |
1180 | mutex_lock(&dentry->d_inode->i_mutex); | 1180 | I_MUTEX_PARENT); |
1181 | mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD); | ||
1181 | if (configfs_detach_prep(dentry)) { | 1182 | if (configfs_detach_prep(dentry)) { |
1182 | printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); | 1183 | printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); |
1183 | } | 1184 | } |
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 68bd5c93ca52..ed678529ebb2 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | struct vfsmount * configfs_mount = NULL; | 39 | struct vfsmount * configfs_mount = NULL; |
40 | struct super_block * configfs_sb = NULL; | 40 | struct super_block * configfs_sb = NULL; |
41 | kmem_cache_t *configfs_dir_cachep; | 41 | struct kmem_cache *configfs_dir_cachep; |
42 | static int configfs_mnt_count = 0; | 42 | static int configfs_mnt_count = 0; |
43 | 43 | ||
44 | static struct super_operations configfs_ops = { | 44 | static struct super_operations configfs_ops = { |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index a624c3ec8189..0509cedd415c 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -481,6 +481,8 @@ static int cramfs_readpage(struct file *file, struct page * page) | |||
481 | pgdata = kmap(page); | 481 | pgdata = kmap(page); |
482 | if (compr_len == 0) | 482 | if (compr_len == 0) |
483 | ; /* hole */ | 483 | ; /* hole */ |
484 | else if (compr_len > (PAGE_CACHE_SIZE << 1)) | ||
485 | printk(KERN_ERR "cramfs: bad compressed blocksize %u\n", compr_len); | ||
484 | else { | 486 | else { |
485 | mutex_lock(&read_mutex); | 487 | mutex_lock(&read_mutex); |
486 | bytes_filled = cramfs_uncompress_block(pgdata, | 488 | bytes_filled = cramfs_uncompress_block(pgdata, |
diff --git a/fs/dcache.c b/fs/dcache.c index fd4a428998ef..d68631f18df1 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -43,7 +43,7 @@ static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); | |||
43 | 43 | ||
44 | EXPORT_SYMBOL(dcache_lock); | 44 | EXPORT_SYMBOL(dcache_lock); |
45 | 45 | ||
46 | static kmem_cache_t *dentry_cache __read_mostly; | 46 | static struct kmem_cache *dentry_cache __read_mostly; |
47 | 47 | ||
48 | #define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname)) | 48 | #define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname)) |
49 | 49 | ||
@@ -68,15 +68,19 @@ struct dentry_stat_t dentry_stat = { | |||
68 | .age_limit = 45, | 68 | .age_limit = 45, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static void d_callback(struct rcu_head *head) | 71 | static void __d_free(struct dentry *dentry) |
72 | { | 72 | { |
73 | struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); | ||
74 | |||
75 | if (dname_external(dentry)) | 73 | if (dname_external(dentry)) |
76 | kfree(dentry->d_name.name); | 74 | kfree(dentry->d_name.name); |
77 | kmem_cache_free(dentry_cache, dentry); | 75 | kmem_cache_free(dentry_cache, dentry); |
78 | } | 76 | } |
79 | 77 | ||
78 | static void d_callback(struct rcu_head *head) | ||
79 | { | ||
80 | struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu); | ||
81 | __d_free(dentry); | ||
82 | } | ||
83 | |||
80 | /* | 84 | /* |
81 | * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry | 85 | * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry |
82 | * inside dcache_lock. | 86 | * inside dcache_lock. |
@@ -85,7 +89,11 @@ static void d_free(struct dentry *dentry) | |||
85 | { | 89 | { |
86 | if (dentry->d_op && dentry->d_op->d_release) | 90 | if (dentry->d_op && dentry->d_op->d_release) |
87 | dentry->d_op->d_release(dentry); | 91 | dentry->d_op->d_release(dentry); |
88 | call_rcu(&dentry->d_u.d_rcu, d_callback); | 92 | /* if dentry was never inserted into hash, immediate free is OK */ |
93 | if (dentry->d_hash.pprev == NULL) | ||
94 | __d_free(dentry); | ||
95 | else | ||
96 | call_rcu(&dentry->d_u.d_rcu, d_callback); | ||
89 | } | 97 | } |
90 | 98 | ||
91 | /* | 99 | /* |
@@ -2072,10 +2080,10 @@ static void __init dcache_init(unsigned long mempages) | |||
2072 | } | 2080 | } |
2073 | 2081 | ||
2074 | /* SLAB cache for __getname() consumers */ | 2082 | /* SLAB cache for __getname() consumers */ |
2075 | kmem_cache_t *names_cachep __read_mostly; | 2083 | struct kmem_cache *names_cachep __read_mostly; |
2076 | 2084 | ||
2077 | /* SLAB cache for file structures */ | 2085 | /* SLAB cache for file structures */ |
2078 | kmem_cache_t *filp_cachep __read_mostly; | 2086 | struct kmem_cache *filp_cachep __read_mostly; |
2079 | 2087 | ||
2080 | EXPORT_SYMBOL(d_genocide); | 2088 | EXPORT_SYMBOL(d_genocide); |
2081 | 2089 | ||
diff --git a/fs/dcookies.c b/fs/dcookies.c index 0c4b0674854b..21af1629f9bc 100644 --- a/fs/dcookies.c +++ b/fs/dcookies.c | |||
@@ -37,7 +37,7 @@ struct dcookie_struct { | |||
37 | 37 | ||
38 | static LIST_HEAD(dcookie_users); | 38 | static LIST_HEAD(dcookie_users); |
39 | static DEFINE_MUTEX(dcookie_mutex); | 39 | static DEFINE_MUTEX(dcookie_mutex); |
40 | static kmem_cache_t *dcookie_cache __read_mostly; | 40 | static struct kmem_cache *dcookie_cache __read_mostly; |
41 | static struct list_head *dcookie_hashtable __read_mostly; | 41 | static struct list_head *dcookie_hashtable __read_mostly; |
42 | static size_t hash_size __read_mostly; | 42 | static size_t hash_size __read_mostly; |
43 | 43 | ||
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index e77676df6713..137d76c3f90a 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
22 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/kobject.h> | ||
24 | #include <linux/namei.h> | 25 | #include <linux/namei.h> |
25 | #include <linux/debugfs.h> | 26 | #include <linux/debugfs.h> |
26 | 27 | ||
@@ -147,13 +148,13 @@ static int debugfs_create_by_name(const char *name, mode_t mode, | |||
147 | *dentry = NULL; | 148 | *dentry = NULL; |
148 | mutex_lock(&parent->d_inode->i_mutex); | 149 | mutex_lock(&parent->d_inode->i_mutex); |
149 | *dentry = lookup_one_len(name, parent, strlen(name)); | 150 | *dentry = lookup_one_len(name, parent, strlen(name)); |
150 | if (!IS_ERR(dentry)) { | 151 | if (!IS_ERR(*dentry)) { |
151 | if ((mode & S_IFMT) == S_IFDIR) | 152 | if ((mode & S_IFMT) == S_IFDIR) |
152 | error = debugfs_mkdir(parent->d_inode, *dentry, mode); | 153 | error = debugfs_mkdir(parent->d_inode, *dentry, mode); |
153 | else | 154 | else |
154 | error = debugfs_create(parent->d_inode, *dentry, mode); | 155 | error = debugfs_create(parent->d_inode, *dentry, mode); |
155 | } else | 156 | } else |
156 | error = PTR_ERR(dentry); | 157 | error = PTR_ERR(*dentry); |
157 | mutex_unlock(&parent->d_inode->i_mutex); | 158 | mutex_unlock(&parent->d_inode->i_mutex); |
158 | 159 | ||
159 | return error; | 160 | return error; |
diff --git a/fs/dlm/Kconfig b/fs/dlm/Kconfig index 81b2c6465eeb..b5654a284fef 100644 --- a/fs/dlm/Kconfig +++ b/fs/dlm/Kconfig | |||
@@ -1,14 +1,32 @@ | |||
1 | menu "Distributed Lock Manager" | 1 | menu "Distributed Lock Manager" |
2 | depends on INET && IP_SCTP && EXPERIMENTAL | 2 | depends on EXPERIMENTAL && INET |
3 | 3 | ||
4 | config DLM | 4 | config DLM |
5 | tristate "Distributed Lock Manager (DLM)" | 5 | tristate "Distributed Lock Manager (DLM)" |
6 | depends on IPV6 || IPV6=n | 6 | depends on IPV6 || IPV6=n |
7 | select CONFIGFS_FS | 7 | select CONFIGFS_FS |
8 | select IP_SCTP if DLM_SCTP | ||
8 | help | 9 | help |
9 | A general purpose distributed lock manager for kernel or userspace | 10 | A general purpose distributed lock manager for kernel or userspace |
10 | applications. | 11 | applications. |
11 | 12 | ||
13 | choice | ||
14 | prompt "Select DLM communications protocol" | ||
15 | depends on DLM | ||
16 | default DLM_TCP | ||
17 | help | ||
18 | The DLM Can use TCP or SCTP for it's network communications. | ||
19 | SCTP supports multi-homed operations whereas TCP doesn't. | ||
20 | However, SCTP seems to have stability problems at the moment. | ||
21 | |||
22 | config DLM_TCP | ||
23 | bool "TCP/IP" | ||
24 | |||
25 | config DLM_SCTP | ||
26 | bool "SCTP" | ||
27 | |||
28 | endchoice | ||
29 | |||
12 | config DLM_DEBUG | 30 | config DLM_DEBUG |
13 | bool "DLM debugging" | 31 | bool "DLM debugging" |
14 | depends on DLM | 32 | depends on DLM |
diff --git a/fs/dlm/Makefile b/fs/dlm/Makefile index 1832e0297f7d..65388944eba0 100644 --- a/fs/dlm/Makefile +++ b/fs/dlm/Makefile | |||
@@ -4,7 +4,6 @@ dlm-y := ast.o \ | |||
4 | dir.o \ | 4 | dir.o \ |
5 | lock.o \ | 5 | lock.o \ |
6 | lockspace.o \ | 6 | lockspace.o \ |
7 | lowcomms.o \ | ||
8 | main.o \ | 7 | main.o \ |
9 | member.o \ | 8 | member.o \ |
10 | memory.o \ | 9 | memory.o \ |
@@ -17,3 +16,6 @@ dlm-y := ast.o \ | |||
17 | util.o | 16 | util.o |
18 | dlm-$(CONFIG_DLM_DEBUG) += debug_fs.o | 17 | dlm-$(CONFIG_DLM_DEBUG) += debug_fs.o |
19 | 18 | ||
19 | dlm-$(CONFIG_DLM_TCP) += lowcomms-tcp.o | ||
20 | |||
21 | dlm-$(CONFIG_DLM_SCTP) += lowcomms-sctp.o \ No newline at end of file | ||
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h index 1e5cd67e1b7a..1ee8195e6fc0 100644 --- a/fs/dlm/dlm_internal.h +++ b/fs/dlm/dlm_internal.h | |||
@@ -471,6 +471,7 @@ struct dlm_ls { | |||
471 | char *ls_recover_buf; | 471 | char *ls_recover_buf; |
472 | int ls_recover_nodeid; /* for debugging */ | 472 | int ls_recover_nodeid; /* for debugging */ |
473 | uint64_t ls_rcom_seq; | 473 | uint64_t ls_rcom_seq; |
474 | spinlock_t ls_rcom_spin; | ||
474 | struct list_head ls_recover_list; | 475 | struct list_head ls_recover_list; |
475 | spinlock_t ls_recover_list_lock; | 476 | spinlock_t ls_recover_list_lock; |
476 | int ls_recover_list_count; | 477 | int ls_recover_list_count; |
@@ -488,7 +489,8 @@ struct dlm_ls { | |||
488 | #define LSFL_RUNNING 1 | 489 | #define LSFL_RUNNING 1 |
489 | #define LSFL_RECOVERY_STOP 2 | 490 | #define LSFL_RECOVERY_STOP 2 |
490 | #define LSFL_RCOM_READY 3 | 491 | #define LSFL_RCOM_READY 3 |
491 | #define LSFL_UEVENT_WAIT 4 | 492 | #define LSFL_RCOM_WAIT 4 |
493 | #define LSFL_UEVENT_WAIT 5 | ||
492 | 494 | ||
493 | /* much of this is just saving user space pointers associated with the | 495 | /* much of this is just saving user space pointers associated with the |
494 | lock that we pass back to the user lib with an ast */ | 496 | lock that we pass back to the user lib with an ast */ |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 3f2befa4797b..30878defaeb6 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
@@ -2372,6 +2372,7 @@ static int send_lookup_reply(struct dlm_ls *ls, struct dlm_message *ms_in, | |||
2372 | static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms) | 2372 | static void receive_flags(struct dlm_lkb *lkb, struct dlm_message *ms) |
2373 | { | 2373 | { |
2374 | lkb->lkb_exflags = ms->m_exflags; | 2374 | lkb->lkb_exflags = ms->m_exflags; |
2375 | lkb->lkb_sbflags = ms->m_sbflags; | ||
2375 | lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) | | 2376 | lkb->lkb_flags = (lkb->lkb_flags & 0xFFFF0000) | |
2376 | (ms->m_flags & 0x0000FFFF); | 2377 | (ms->m_flags & 0x0000FFFF); |
2377 | } | 2378 | } |
@@ -3028,10 +3029,17 @@ int dlm_receive_message(struct dlm_header *hd, int nodeid, int recovery) | |||
3028 | 3029 | ||
3029 | while (1) { | 3030 | while (1) { |
3030 | if (dlm_locking_stopped(ls)) { | 3031 | if (dlm_locking_stopped(ls)) { |
3031 | if (!recovery) | 3032 | if (recovery) { |
3032 | dlm_add_requestqueue(ls, nodeid, hd); | 3033 | error = -EINTR; |
3033 | error = -EINTR; | 3034 | goto out; |
3034 | goto out; | 3035 | } |
3036 | error = dlm_add_requestqueue(ls, nodeid, hd); | ||
3037 | if (error == -EAGAIN) | ||
3038 | continue; | ||
3039 | else { | ||
3040 | error = -EINTR; | ||
3041 | goto out; | ||
3042 | } | ||
3035 | } | 3043 | } |
3036 | 3044 | ||
3037 | if (lock_recovery_try(ls)) | 3045 | if (lock_recovery_try(ls)) |
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index 109333c8ecb9..59012b089e8d 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "memory.h" | 22 | #include "memory.h" |
23 | #include "lock.h" | 23 | #include "lock.h" |
24 | #include "recover.h" | 24 | #include "recover.h" |
25 | #include "requestqueue.h" | ||
25 | 26 | ||
26 | #ifdef CONFIG_DLM_DEBUG | 27 | #ifdef CONFIG_DLM_DEBUG |
27 | int dlm_create_debug_file(struct dlm_ls *ls); | 28 | int dlm_create_debug_file(struct dlm_ls *ls); |
@@ -43,6 +44,10 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len) | |||
43 | ssize_t ret = len; | 44 | ssize_t ret = len; |
44 | int n = simple_strtol(buf, NULL, 0); | 45 | int n = simple_strtol(buf, NULL, 0); |
45 | 46 | ||
47 | ls = dlm_find_lockspace_local(ls->ls_local_handle); | ||
48 | if (!ls) | ||
49 | return -EINVAL; | ||
50 | |||
46 | switch (n) { | 51 | switch (n) { |
47 | case 0: | 52 | case 0: |
48 | dlm_ls_stop(ls); | 53 | dlm_ls_stop(ls); |
@@ -53,6 +58,7 @@ static ssize_t dlm_control_store(struct dlm_ls *ls, const char *buf, size_t len) | |||
53 | default: | 58 | default: |
54 | ret = -EINVAL; | 59 | ret = -EINVAL; |
55 | } | 60 | } |
61 | dlm_put_lockspace(ls); | ||
56 | return ret; | 62 | return ret; |
57 | } | 63 | } |
58 | 64 | ||
@@ -143,6 +149,12 @@ static ssize_t dlm_attr_store(struct kobject *kobj, struct attribute *attr, | |||
143 | return a->store ? a->store(ls, buf, len) : len; | 149 | return a->store ? a->store(ls, buf, len) : len; |
144 | } | 150 | } |
145 | 151 | ||
152 | static void lockspace_kobj_release(struct kobject *k) | ||
153 | { | ||
154 | struct dlm_ls *ls = container_of(k, struct dlm_ls, ls_kobj); | ||
155 | kfree(ls); | ||
156 | } | ||
157 | |||
146 | static struct sysfs_ops dlm_attr_ops = { | 158 | static struct sysfs_ops dlm_attr_ops = { |
147 | .show = dlm_attr_show, | 159 | .show = dlm_attr_show, |
148 | .store = dlm_attr_store, | 160 | .store = dlm_attr_store, |
@@ -151,6 +163,7 @@ static struct sysfs_ops dlm_attr_ops = { | |||
151 | static struct kobj_type dlm_ktype = { | 163 | static struct kobj_type dlm_ktype = { |
152 | .default_attrs = dlm_attrs, | 164 | .default_attrs = dlm_attrs, |
153 | .sysfs_ops = &dlm_attr_ops, | 165 | .sysfs_ops = &dlm_attr_ops, |
166 | .release = lockspace_kobj_release, | ||
154 | }; | 167 | }; |
155 | 168 | ||
156 | static struct kset dlm_kset = { | 169 | static struct kset dlm_kset = { |
@@ -466,6 +479,8 @@ static int new_lockspace(char *name, int namelen, void **lockspace, | |||
466 | ls->ls_recoverd_task = NULL; | 479 | ls->ls_recoverd_task = NULL; |
467 | mutex_init(&ls->ls_recoverd_active); | 480 | mutex_init(&ls->ls_recoverd_active); |
468 | spin_lock_init(&ls->ls_recover_lock); | 481 | spin_lock_init(&ls->ls_recover_lock); |
482 | spin_lock_init(&ls->ls_rcom_spin); | ||
483 | get_random_bytes(&ls->ls_rcom_seq, sizeof(uint64_t)); | ||
469 | ls->ls_recover_status = 0; | 484 | ls->ls_recover_status = 0; |
470 | ls->ls_recover_seq = 0; | 485 | ls->ls_recover_seq = 0; |
471 | ls->ls_recover_args = NULL; | 486 | ls->ls_recover_args = NULL; |
@@ -672,13 +687,14 @@ static int release_lockspace(struct dlm_ls *ls, int force) | |||
672 | * Free structures on any other lists | 687 | * Free structures on any other lists |
673 | */ | 688 | */ |
674 | 689 | ||
690 | dlm_purge_requestqueue(ls); | ||
675 | kfree(ls->ls_recover_args); | 691 | kfree(ls->ls_recover_args); |
676 | dlm_clear_free_entries(ls); | 692 | dlm_clear_free_entries(ls); |
677 | dlm_clear_members(ls); | 693 | dlm_clear_members(ls); |
678 | dlm_clear_members_gone(ls); | 694 | dlm_clear_members_gone(ls); |
679 | kfree(ls->ls_node_array); | 695 | kfree(ls->ls_node_array); |
680 | kobject_unregister(&ls->ls_kobj); | 696 | kobject_unregister(&ls->ls_kobj); |
681 | kfree(ls); | 697 | /* The ls structure will be freed when the kobject is done with */ |
682 | 698 | ||
683 | mutex_lock(&ls_lock); | 699 | mutex_lock(&ls_lock); |
684 | ls_count--; | 700 | ls_count--; |
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms-sctp.c index 6da6b14d5a61..fe158d7a9285 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms-sctp.c | |||
@@ -2,7 +2,7 @@ | |||
2 | ******************************************************************************* | 2 | ******************************************************************************* |
3 | ** | 3 | ** |
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
5 | ** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved. | 5 | ** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
6 | ** | 6 | ** |
7 | ** This copyrighted material is made available to anyone wishing to use, | 7 | ** This copyrighted material is made available to anyone wishing to use, |
8 | ** modify, copy, or redistribute it subject to the terms and conditions | 8 | ** modify, copy, or redistribute it subject to the terms and conditions |
@@ -75,13 +75,13 @@ struct nodeinfo { | |||
75 | }; | 75 | }; |
76 | 76 | ||
77 | static DEFINE_IDR(nodeinfo_idr); | 77 | static DEFINE_IDR(nodeinfo_idr); |
78 | static struct rw_semaphore nodeinfo_lock; | 78 | static DECLARE_RWSEM(nodeinfo_lock); |
79 | static int max_nodeid; | 79 | static int max_nodeid; |
80 | 80 | ||
81 | struct cbuf { | 81 | struct cbuf { |
82 | unsigned base; | 82 | unsigned int base; |
83 | unsigned len; | 83 | unsigned int len; |
84 | unsigned mask; | 84 | unsigned int mask; |
85 | }; | 85 | }; |
86 | 86 | ||
87 | /* Just the one of these, now. But this struct keeps | 87 | /* Just the one of these, now. But this struct keeps |
@@ -90,9 +90,9 @@ struct cbuf { | |||
90 | #define CF_READ_PENDING 1 | 90 | #define CF_READ_PENDING 1 |
91 | 91 | ||
92 | struct connection { | 92 | struct connection { |
93 | struct socket *sock; | 93 | struct socket *sock; |
94 | unsigned long flags; | 94 | unsigned long flags; |
95 | struct page *rx_page; | 95 | struct page *rx_page; |
96 | atomic_t waiting_requests; | 96 | atomic_t waiting_requests; |
97 | struct cbuf cb; | 97 | struct cbuf cb; |
98 | int eagain_flag; | 98 | int eagain_flag; |
@@ -102,36 +102,40 @@ struct connection { | |||
102 | 102 | ||
103 | struct writequeue_entry { | 103 | struct writequeue_entry { |
104 | struct list_head list; | 104 | struct list_head list; |
105 | struct page *page; | 105 | struct page *page; |
106 | int offset; | 106 | int offset; |
107 | int len; | 107 | int len; |
108 | int end; | 108 | int end; |
109 | int users; | 109 | int users; |
110 | struct nodeinfo *ni; | 110 | struct nodeinfo *ni; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | #define CBUF_ADD(cb, n) do { (cb)->len += n; } while(0) | 113 | static void cbuf_add(struct cbuf *cb, int n) |
114 | #define CBUF_EMPTY(cb) ((cb)->len == 0) | 114 | { |
115 | #define CBUF_MAY_ADD(cb, n) (((cb)->len + (n)) < ((cb)->mask + 1)) | 115 | cb->len += n; |
116 | #define CBUF_DATA(cb) (((cb)->base + (cb)->len) & (cb)->mask) | 116 | } |
117 | 117 | ||
118 | #define CBUF_INIT(cb, size) \ | 118 | static int cbuf_data(struct cbuf *cb) |
119 | do { \ | 119 | { |
120 | (cb)->base = (cb)->len = 0; \ | 120 | return ((cb->base + cb->len) & cb->mask); |
121 | (cb)->mask = ((size)-1); \ | 121 | } |
122 | } while(0) | ||
123 | 122 | ||
124 | #define CBUF_EAT(cb, n) \ | 123 | static void cbuf_init(struct cbuf *cb, int size) |
125 | do { \ | 124 | { |
126 | (cb)->len -= (n); \ | 125 | cb->base = cb->len = 0; |
127 | (cb)->base += (n); \ | 126 | cb->mask = size-1; |
128 | (cb)->base &= (cb)->mask; \ | 127 | } |
129 | } while(0) | ||
130 | 128 | ||
129 | static void cbuf_eat(struct cbuf *cb, int n) | ||
130 | { | ||
131 | cb->len -= n; | ||
132 | cb->base += n; | ||
133 | cb->base &= cb->mask; | ||
134 | } | ||
131 | 135 | ||
132 | /* List of nodes which have writes pending */ | 136 | /* List of nodes which have writes pending */ |
133 | static struct list_head write_nodes; | 137 | static LIST_HEAD(write_nodes); |
134 | static spinlock_t write_nodes_lock; | 138 | static DEFINE_SPINLOCK(write_nodes_lock); |
135 | 139 | ||
136 | /* Maximum number of incoming messages to process before | 140 | /* Maximum number of incoming messages to process before |
137 | * doing a schedule() | 141 | * doing a schedule() |
@@ -141,8 +145,7 @@ static spinlock_t write_nodes_lock; | |||
141 | /* Manage daemons */ | 145 | /* Manage daemons */ |
142 | static struct task_struct *recv_task; | 146 | static struct task_struct *recv_task; |
143 | static struct task_struct *send_task; | 147 | static struct task_struct *send_task; |
144 | static wait_queue_head_t lowcomms_recv_wait; | 148 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_recv_wait); |
145 | static atomic_t accepting; | ||
146 | 149 | ||
147 | /* The SCTP connection */ | 150 | /* The SCTP connection */ |
148 | static struct connection sctp_con; | 151 | static struct connection sctp_con; |
@@ -161,11 +164,11 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) | |||
161 | return error; | 164 | return error; |
162 | 165 | ||
163 | if (dlm_local_addr[0]->ss_family == AF_INET) { | 166 | if (dlm_local_addr[0]->ss_family == AF_INET) { |
164 | struct sockaddr_in *in4 = (struct sockaddr_in *) &addr; | 167 | struct sockaddr_in *in4 = (struct sockaddr_in *) &addr; |
165 | struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr; | 168 | struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr; |
166 | ret4->sin_addr.s_addr = in4->sin_addr.s_addr; | 169 | ret4->sin_addr.s_addr = in4->sin_addr.s_addr; |
167 | } else { | 170 | } else { |
168 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; | 171 | struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &addr; |
169 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; | 172 | struct sockaddr_in6 *ret6 = (struct sockaddr_in6 *) retaddr; |
170 | memcpy(&ret6->sin6_addr, &in6->sin6_addr, | 173 | memcpy(&ret6->sin6_addr, &in6->sin6_addr, |
171 | sizeof(in6->sin6_addr)); | 174 | sizeof(in6->sin6_addr)); |
@@ -174,6 +177,8 @@ static int nodeid_to_addr(int nodeid, struct sockaddr *retaddr) | |||
174 | return 0; | 177 | return 0; |
175 | } | 178 | } |
176 | 179 | ||
180 | /* If alloc is 0 here we will not attempt to allocate a new | ||
181 | nodeinfo struct */ | ||
177 | static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) | 182 | static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) |
178 | { | 183 | { |
179 | struct nodeinfo *ni; | 184 | struct nodeinfo *ni; |
@@ -184,44 +189,45 @@ static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc) | |||
184 | ni = idr_find(&nodeinfo_idr, nodeid); | 189 | ni = idr_find(&nodeinfo_idr, nodeid); |
185 | up_read(&nodeinfo_lock); | 190 | up_read(&nodeinfo_lock); |
186 | 191 | ||
187 | if (!ni && alloc) { | 192 | if (ni || !alloc) |
188 | down_write(&nodeinfo_lock); | 193 | return ni; |
189 | 194 | ||
190 | ni = idr_find(&nodeinfo_idr, nodeid); | 195 | down_write(&nodeinfo_lock); |
191 | if (ni) | ||
192 | goto out_up; | ||
193 | 196 | ||
194 | r = idr_pre_get(&nodeinfo_idr, alloc); | 197 | ni = idr_find(&nodeinfo_idr, nodeid); |
195 | if (!r) | 198 | if (ni) |
196 | goto out_up; | 199 | goto out_up; |
197 | 200 | ||
198 | ni = kmalloc(sizeof(struct nodeinfo), alloc); | 201 | r = idr_pre_get(&nodeinfo_idr, alloc); |
199 | if (!ni) | 202 | if (!r) |
200 | goto out_up; | 203 | goto out_up; |
201 | 204 | ||
202 | r = idr_get_new_above(&nodeinfo_idr, ni, nodeid, &n); | 205 | ni = kmalloc(sizeof(struct nodeinfo), alloc); |
203 | if (r) { | 206 | if (!ni) |
204 | kfree(ni); | 207 | goto out_up; |
205 | ni = NULL; | 208 | |
206 | goto out_up; | 209 | r = idr_get_new_above(&nodeinfo_idr, ni, nodeid, &n); |
207 | } | 210 | if (r) { |
208 | if (n != nodeid) { | 211 | kfree(ni); |
209 | idr_remove(&nodeinfo_idr, n); | 212 | ni = NULL; |
210 | kfree(ni); | 213 | goto out_up; |
211 | ni = NULL; | ||
212 | goto out_up; | ||
213 | } | ||
214 | memset(ni, 0, sizeof(struct nodeinfo)); | ||
215 | spin_lock_init(&ni->lock); | ||
216 | INIT_LIST_HEAD(&ni->writequeue); | ||
217 | spin_lock_init(&ni->writequeue_lock); | ||
218 | ni->nodeid = nodeid; | ||
219 | |||
220 | if (nodeid > max_nodeid) | ||
221 | max_nodeid = nodeid; | ||
222 | out_up: | ||
223 | up_write(&nodeinfo_lock); | ||
224 | } | 214 | } |
215 | if (n != nodeid) { | ||
216 | idr_remove(&nodeinfo_idr, n); | ||
217 | kfree(ni); | ||
218 | ni = NULL; | ||
219 | goto out_up; | ||
220 | } | ||
221 | memset(ni, 0, sizeof(struct nodeinfo)); | ||
222 | spin_lock_init(&ni->lock); | ||
223 | INIT_LIST_HEAD(&ni->writequeue); | ||
224 | spin_lock_init(&ni->writequeue_lock); | ||
225 | ni->nodeid = nodeid; | ||
226 | |||
227 | if (nodeid > max_nodeid) | ||
228 | max_nodeid = nodeid; | ||
229 | out_up: | ||
230 | up_write(&nodeinfo_lock); | ||
225 | 231 | ||
226 | return ni; | 232 | return ni; |
227 | } | 233 | } |
@@ -279,13 +285,13 @@ static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port, | |||
279 | in4_addr->sin_port = cpu_to_be16(port); | 285 | in4_addr->sin_port = cpu_to_be16(port); |
280 | memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero)); | 286 | memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero)); |
281 | memset(in4_addr+1, 0, sizeof(struct sockaddr_storage) - | 287 | memset(in4_addr+1, 0, sizeof(struct sockaddr_storage) - |
282 | sizeof(struct sockaddr_in)); | 288 | sizeof(struct sockaddr_in)); |
283 | *addr_len = sizeof(struct sockaddr_in); | 289 | *addr_len = sizeof(struct sockaddr_in); |
284 | } else { | 290 | } else { |
285 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; | 291 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; |
286 | in6_addr->sin6_port = cpu_to_be16(port); | 292 | in6_addr->sin6_port = cpu_to_be16(port); |
287 | memset(in6_addr+1, 0, sizeof(struct sockaddr_storage) - | 293 | memset(in6_addr+1, 0, sizeof(struct sockaddr_storage) - |
288 | sizeof(struct sockaddr_in6)); | 294 | sizeof(struct sockaddr_in6)); |
289 | *addr_len = sizeof(struct sockaddr_in6); | 295 | *addr_len = sizeof(struct sockaddr_in6); |
290 | } | 296 | } |
291 | } | 297 | } |
@@ -324,7 +330,7 @@ static void send_shutdown(sctp_assoc_t associd) | |||
324 | cmsg->cmsg_type = SCTP_SNDRCV; | 330 | cmsg->cmsg_type = SCTP_SNDRCV; |
325 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 331 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
326 | outmessage.msg_controllen = cmsg->cmsg_len; | 332 | outmessage.msg_controllen = cmsg->cmsg_len; |
327 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 333 | sinfo = CMSG_DATA(cmsg); |
328 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 334 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
329 | 335 | ||
330 | sinfo->sinfo_flags |= MSG_EOF; | 336 | sinfo->sinfo_flags |= MSG_EOF; |
@@ -387,7 +393,7 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
387 | 393 | ||
388 | if ((int)sn->sn_assoc_change.sac_assoc_id <= 0) { | 394 | if ((int)sn->sn_assoc_change.sac_assoc_id <= 0) { |
389 | log_print("COMM_UP for invalid assoc ID %d", | 395 | log_print("COMM_UP for invalid assoc ID %d", |
390 | (int)sn->sn_assoc_change.sac_assoc_id); | 396 | (int)sn->sn_assoc_change.sac_assoc_id); |
391 | init_failed(); | 397 | init_failed(); |
392 | return; | 398 | return; |
393 | } | 399 | } |
@@ -398,15 +404,18 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
398 | fs = get_fs(); | 404 | fs = get_fs(); |
399 | set_fs(get_ds()); | 405 | set_fs(get_ds()); |
400 | ret = sctp_con.sock->ops->getsockopt(sctp_con.sock, | 406 | ret = sctp_con.sock->ops->getsockopt(sctp_con.sock, |
401 | IPPROTO_SCTP, SCTP_PRIMARY_ADDR, | 407 | IPPROTO_SCTP, |
402 | (char*)&prim, &prim_len); | 408 | SCTP_PRIMARY_ADDR, |
409 | (char*)&prim, | ||
410 | &prim_len); | ||
403 | set_fs(fs); | 411 | set_fs(fs); |
404 | if (ret < 0) { | 412 | if (ret < 0) { |
405 | struct nodeinfo *ni; | 413 | struct nodeinfo *ni; |
406 | 414 | ||
407 | log_print("getsockopt/sctp_primary_addr on " | 415 | log_print("getsockopt/sctp_primary_addr on " |
408 | "new assoc %d failed : %d", | 416 | "new assoc %d failed : %d", |
409 | (int)sn->sn_assoc_change.sac_assoc_id, ret); | 417 | (int)sn->sn_assoc_change.sac_assoc_id, |
418 | ret); | ||
410 | 419 | ||
411 | /* Retry INIT later */ | 420 | /* Retry INIT later */ |
412 | ni = assoc2nodeinfo(sn->sn_assoc_change.sac_assoc_id); | 421 | ni = assoc2nodeinfo(sn->sn_assoc_change.sac_assoc_id); |
@@ -426,12 +435,10 @@ static void process_sctp_notification(struct msghdr *msg, char *buf) | |||
426 | return; | 435 | return; |
427 | 436 | ||
428 | /* Save the assoc ID */ | 437 | /* Save the assoc ID */ |
429 | spin_lock(&ni->lock); | ||
430 | ni->assoc_id = sn->sn_assoc_change.sac_assoc_id; | 438 | ni->assoc_id = sn->sn_assoc_change.sac_assoc_id; |
431 | spin_unlock(&ni->lock); | ||
432 | 439 | ||
433 | log_print("got new/restarted association %d nodeid %d", | 440 | log_print("got new/restarted association %d nodeid %d", |
434 | (int)sn->sn_assoc_change.sac_assoc_id, nodeid); | 441 | (int)sn->sn_assoc_change.sac_assoc_id, nodeid); |
435 | 442 | ||
436 | /* Send any pending writes */ | 443 | /* Send any pending writes */ |
437 | clear_bit(NI_INIT_PENDING, &ni->flags); | 444 | clear_bit(NI_INIT_PENDING, &ni->flags); |
@@ -507,13 +514,12 @@ static int receive_from_sock(void) | |||
507 | sctp_con.rx_page = alloc_page(GFP_ATOMIC); | 514 | sctp_con.rx_page = alloc_page(GFP_ATOMIC); |
508 | if (sctp_con.rx_page == NULL) | 515 | if (sctp_con.rx_page == NULL) |
509 | goto out_resched; | 516 | goto out_resched; |
510 | CBUF_INIT(&sctp_con.cb, PAGE_CACHE_SIZE); | 517 | cbuf_init(&sctp_con.cb, PAGE_CACHE_SIZE); |
511 | } | 518 | } |
512 | 519 | ||
513 | memset(&incmsg, 0, sizeof(incmsg)); | 520 | memset(&incmsg, 0, sizeof(incmsg)); |
514 | memset(&msgname, 0, sizeof(msgname)); | 521 | memset(&msgname, 0, sizeof(msgname)); |
515 | 522 | ||
516 | memset(incmsg, 0, sizeof(incmsg)); | ||
517 | msg.msg_name = &msgname; | 523 | msg.msg_name = &msgname; |
518 | msg.msg_namelen = sizeof(msgname); | 524 | msg.msg_namelen = sizeof(msgname); |
519 | msg.msg_flags = 0; | 525 | msg.msg_flags = 0; |
@@ -532,17 +538,17 @@ static int receive_from_sock(void) | |||
532 | * iov[0] is the bit of the circular buffer between the current end | 538 | * iov[0] is the bit of the circular buffer between the current end |
533 | * point (cb.base + cb.len) and the end of the buffer. | 539 | * point (cb.base + cb.len) and the end of the buffer. |
534 | */ | 540 | */ |
535 | iov[0].iov_len = sctp_con.cb.base - CBUF_DATA(&sctp_con.cb); | 541 | iov[0].iov_len = sctp_con.cb.base - cbuf_data(&sctp_con.cb); |
536 | iov[0].iov_base = page_address(sctp_con.rx_page) + | 542 | iov[0].iov_base = page_address(sctp_con.rx_page) + |
537 | CBUF_DATA(&sctp_con.cb); | 543 | cbuf_data(&sctp_con.cb); |
538 | iov[1].iov_len = 0; | 544 | iov[1].iov_len = 0; |
539 | 545 | ||
540 | /* | 546 | /* |
541 | * iov[1] is the bit of the circular buffer between the start of the | 547 | * iov[1] is the bit of the circular buffer between the start of the |
542 | * buffer and the start of the currently used section (cb.base) | 548 | * buffer and the start of the currently used section (cb.base) |
543 | */ | 549 | */ |
544 | if (CBUF_DATA(&sctp_con.cb) >= sctp_con.cb.base) { | 550 | if (cbuf_data(&sctp_con.cb) >= sctp_con.cb.base) { |
545 | iov[0].iov_len = PAGE_CACHE_SIZE - CBUF_DATA(&sctp_con.cb); | 551 | iov[0].iov_len = PAGE_CACHE_SIZE - cbuf_data(&sctp_con.cb); |
546 | iov[1].iov_len = sctp_con.cb.base; | 552 | iov[1].iov_len = sctp_con.cb.base; |
547 | iov[1].iov_base = page_address(sctp_con.rx_page); | 553 | iov[1].iov_base = page_address(sctp_con.rx_page); |
548 | msg.msg_iovlen = 2; | 554 | msg.msg_iovlen = 2; |
@@ -557,7 +563,7 @@ static int receive_from_sock(void) | |||
557 | msg.msg_control = incmsg; | 563 | msg.msg_control = incmsg; |
558 | msg.msg_controllen = sizeof(incmsg); | 564 | msg.msg_controllen = sizeof(incmsg); |
559 | cmsg = CMSG_FIRSTHDR(&msg); | 565 | cmsg = CMSG_FIRSTHDR(&msg); |
560 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 566 | sinfo = CMSG_DATA(cmsg); |
561 | 567 | ||
562 | if (msg.msg_flags & MSG_NOTIFICATION) { | 568 | if (msg.msg_flags & MSG_NOTIFICATION) { |
563 | process_sctp_notification(&msg, page_address(sctp_con.rx_page)); | 569 | process_sctp_notification(&msg, page_address(sctp_con.rx_page)); |
@@ -583,29 +589,29 @@ static int receive_from_sock(void) | |||
583 | if (r == 1) | 589 | if (r == 1) |
584 | return 0; | 590 | return 0; |
585 | 591 | ||
586 | CBUF_ADD(&sctp_con.cb, ret); | 592 | cbuf_add(&sctp_con.cb, ret); |
587 | ret = dlm_process_incoming_buffer(cpu_to_le32(sinfo->sinfo_ppid), | 593 | ret = dlm_process_incoming_buffer(cpu_to_le32(sinfo->sinfo_ppid), |
588 | page_address(sctp_con.rx_page), | 594 | page_address(sctp_con.rx_page), |
589 | sctp_con.cb.base, sctp_con.cb.len, | 595 | sctp_con.cb.base, sctp_con.cb.len, |
590 | PAGE_CACHE_SIZE); | 596 | PAGE_CACHE_SIZE); |
591 | if (ret < 0) | 597 | if (ret < 0) |
592 | goto out_close; | 598 | goto out_close; |
593 | CBUF_EAT(&sctp_con.cb, ret); | 599 | cbuf_eat(&sctp_con.cb, ret); |
594 | 600 | ||
595 | out: | 601 | out: |
596 | ret = 0; | 602 | ret = 0; |
597 | goto out_ret; | 603 | goto out_ret; |
598 | 604 | ||
599 | out_resched: | 605 | out_resched: |
600 | lowcomms_data_ready(sctp_con.sock->sk, 0); | 606 | lowcomms_data_ready(sctp_con.sock->sk, 0); |
601 | ret = 0; | 607 | ret = 0; |
602 | schedule(); | 608 | cond_resched(); |
603 | goto out_ret; | 609 | goto out_ret; |
604 | 610 | ||
605 | out_close: | 611 | out_close: |
606 | if (ret != -EAGAIN) | 612 | if (ret != -EAGAIN) |
607 | log_print("error reading from sctp socket: %d", ret); | 613 | log_print("error reading from sctp socket: %d", ret); |
608 | out_ret: | 614 | out_ret: |
609 | return ret; | 615 | return ret; |
610 | } | 616 | } |
611 | 617 | ||
@@ -619,10 +625,12 @@ static int add_bind_addr(struct sockaddr_storage *addr, int addr_len, int num) | |||
619 | set_fs(get_ds()); | 625 | set_fs(get_ds()); |
620 | if (num == 1) | 626 | if (num == 1) |
621 | result = sctp_con.sock->ops->bind(sctp_con.sock, | 627 | result = sctp_con.sock->ops->bind(sctp_con.sock, |
622 | (struct sockaddr *) addr, addr_len); | 628 | (struct sockaddr *) addr, |
629 | addr_len); | ||
623 | else | 630 | else |
624 | result = sctp_con.sock->ops->setsockopt(sctp_con.sock, SOL_SCTP, | 631 | result = sctp_con.sock->ops->setsockopt(sctp_con.sock, SOL_SCTP, |
625 | SCTP_SOCKOPT_BINDX_ADD, (char *)addr, addr_len); | 632 | SCTP_SOCKOPT_BINDX_ADD, |
633 | (char *)addr, addr_len); | ||
626 | set_fs(fs); | 634 | set_fs(fs); |
627 | 635 | ||
628 | if (result < 0) | 636 | if (result < 0) |
@@ -719,10 +727,10 @@ static int init_sock(void) | |||
719 | 727 | ||
720 | return 0; | 728 | return 0; |
721 | 729 | ||
722 | create_delsock: | 730 | create_delsock: |
723 | sock_release(sock); | 731 | sock_release(sock); |
724 | sctp_con.sock = NULL; | 732 | sctp_con.sock = NULL; |
725 | out: | 733 | out: |
726 | return result; | 734 | return result; |
727 | } | 735 | } |
728 | 736 | ||
@@ -756,16 +764,13 @@ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc) | |||
756 | int users = 0; | 764 | int users = 0; |
757 | struct nodeinfo *ni; | 765 | struct nodeinfo *ni; |
758 | 766 | ||
759 | if (!atomic_read(&accepting)) | ||
760 | return NULL; | ||
761 | |||
762 | ni = nodeid2nodeinfo(nodeid, allocation); | 767 | ni = nodeid2nodeinfo(nodeid, allocation); |
763 | if (!ni) | 768 | if (!ni) |
764 | return NULL; | 769 | return NULL; |
765 | 770 | ||
766 | spin_lock(&ni->writequeue_lock); | 771 | spin_lock(&ni->writequeue_lock); |
767 | e = list_entry(ni->writequeue.prev, struct writequeue_entry, list); | 772 | e = list_entry(ni->writequeue.prev, struct writequeue_entry, list); |
768 | if (((struct list_head *) e == &ni->writequeue) || | 773 | if ((&e->list == &ni->writequeue) || |
769 | (PAGE_CACHE_SIZE - e->end < len)) { | 774 | (PAGE_CACHE_SIZE - e->end < len)) { |
770 | e = NULL; | 775 | e = NULL; |
771 | } else { | 776 | } else { |
@@ -776,7 +781,7 @@ void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc) | |||
776 | spin_unlock(&ni->writequeue_lock); | 781 | spin_unlock(&ni->writequeue_lock); |
777 | 782 | ||
778 | if (e) { | 783 | if (e) { |
779 | got_one: | 784 | got_one: |
780 | if (users == 0) | 785 | if (users == 0) |
781 | kmap(e->page); | 786 | kmap(e->page); |
782 | *ppc = page_address(e->page) + offset; | 787 | *ppc = page_address(e->page) + offset; |
@@ -803,9 +808,6 @@ void dlm_lowcomms_commit_buffer(void *arg) | |||
803 | int users; | 808 | int users; |
804 | struct nodeinfo *ni = e->ni; | 809 | struct nodeinfo *ni = e->ni; |
805 | 810 | ||
806 | if (!atomic_read(&accepting)) | ||
807 | return; | ||
808 | |||
809 | spin_lock(&ni->writequeue_lock); | 811 | spin_lock(&ni->writequeue_lock); |
810 | users = --e->users; | 812 | users = --e->users; |
811 | if (users) | 813 | if (users) |
@@ -822,7 +824,7 @@ void dlm_lowcomms_commit_buffer(void *arg) | |||
822 | } | 824 | } |
823 | return; | 825 | return; |
824 | 826 | ||
825 | out: | 827 | out: |
826 | spin_unlock(&ni->writequeue_lock); | 828 | spin_unlock(&ni->writequeue_lock); |
827 | return; | 829 | return; |
828 | } | 830 | } |
@@ -878,7 +880,7 @@ static void initiate_association(int nodeid) | |||
878 | cmsg->cmsg_level = IPPROTO_SCTP; | 880 | cmsg->cmsg_level = IPPROTO_SCTP; |
879 | cmsg->cmsg_type = SCTP_SNDRCV; | 881 | cmsg->cmsg_type = SCTP_SNDRCV; |
880 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 882 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
881 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 883 | sinfo = CMSG_DATA(cmsg); |
882 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 884 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
883 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); | 885 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); |
884 | 886 | ||
@@ -892,7 +894,7 @@ static void initiate_association(int nodeid) | |||
892 | } | 894 | } |
893 | 895 | ||
894 | /* Send a message */ | 896 | /* Send a message */ |
895 | static int send_to_sock(struct nodeinfo *ni) | 897 | static void send_to_sock(struct nodeinfo *ni) |
896 | { | 898 | { |
897 | int ret = 0; | 899 | int ret = 0; |
898 | struct writequeue_entry *e; | 900 | struct writequeue_entry *e; |
@@ -903,13 +905,13 @@ static int send_to_sock(struct nodeinfo *ni) | |||
903 | struct sctp_sndrcvinfo *sinfo; | 905 | struct sctp_sndrcvinfo *sinfo; |
904 | struct kvec iov; | 906 | struct kvec iov; |
905 | 907 | ||
906 | /* See if we need to init an association before we start | 908 | /* See if we need to init an association before we start |
907 | sending precious messages */ | 909 | sending precious messages */ |
908 | spin_lock(&ni->lock); | 910 | spin_lock(&ni->lock); |
909 | if (!ni->assoc_id && !test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { | 911 | if (!ni->assoc_id && !test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { |
910 | spin_unlock(&ni->lock); | 912 | spin_unlock(&ni->lock); |
911 | initiate_association(ni->nodeid); | 913 | initiate_association(ni->nodeid); |
912 | return 0; | 914 | return; |
913 | } | 915 | } |
914 | spin_unlock(&ni->lock); | 916 | spin_unlock(&ni->lock); |
915 | 917 | ||
@@ -923,7 +925,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
923 | cmsg->cmsg_level = IPPROTO_SCTP; | 925 | cmsg->cmsg_level = IPPROTO_SCTP; |
924 | cmsg->cmsg_type = SCTP_SNDRCV; | 926 | cmsg->cmsg_type = SCTP_SNDRCV; |
925 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); | 927 | cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); |
926 | sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); | 928 | sinfo = CMSG_DATA(cmsg); |
927 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); | 929 | memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); |
928 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); | 930 | sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid); |
929 | sinfo->sinfo_assoc_id = ni->assoc_id; | 931 | sinfo->sinfo_assoc_id = ni->assoc_id; |
@@ -955,7 +957,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
955 | goto send_error; | 957 | goto send_error; |
956 | } else { | 958 | } else { |
957 | /* Don't starve people filling buffers */ | 959 | /* Don't starve people filling buffers */ |
958 | schedule(); | 960 | cond_resched(); |
959 | } | 961 | } |
960 | 962 | ||
961 | spin_lock(&ni->writequeue_lock); | 963 | spin_lock(&ni->writequeue_lock); |
@@ -964,15 +966,16 @@ static int send_to_sock(struct nodeinfo *ni) | |||
964 | 966 | ||
965 | if (e->len == 0 && e->users == 0) { | 967 | if (e->len == 0 && e->users == 0) { |
966 | list_del(&e->list); | 968 | list_del(&e->list); |
969 | kunmap(e->page); | ||
967 | free_entry(e); | 970 | free_entry(e); |
968 | continue; | 971 | continue; |
969 | } | 972 | } |
970 | } | 973 | } |
971 | spin_unlock(&ni->writequeue_lock); | 974 | spin_unlock(&ni->writequeue_lock); |
972 | out: | 975 | out: |
973 | return ret; | 976 | return; |
974 | 977 | ||
975 | send_error: | 978 | send_error: |
976 | log_print("Error sending to node %d %d", ni->nodeid, ret); | 979 | log_print("Error sending to node %d %d", ni->nodeid, ret); |
977 | spin_lock(&ni->lock); | 980 | spin_lock(&ni->lock); |
978 | if (!test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { | 981 | if (!test_and_set_bit(NI_INIT_PENDING, &ni->flags)) { |
@@ -982,7 +985,7 @@ static int send_to_sock(struct nodeinfo *ni) | |||
982 | } else | 985 | } else |
983 | spin_unlock(&ni->lock); | 986 | spin_unlock(&ni->lock); |
984 | 987 | ||
985 | return ret; | 988 | return; |
986 | } | 989 | } |
987 | 990 | ||
988 | /* Try to send any messages that are pending */ | 991 | /* Try to send any messages that are pending */ |
@@ -994,7 +997,7 @@ static void process_output_queue(void) | |||
994 | spin_lock_bh(&write_nodes_lock); | 997 | spin_lock_bh(&write_nodes_lock); |
995 | list_for_each_safe(list, temp, &write_nodes) { | 998 | list_for_each_safe(list, temp, &write_nodes) { |
996 | struct nodeinfo *ni = | 999 | struct nodeinfo *ni = |
997 | list_entry(list, struct nodeinfo, write_list); | 1000 | list_entry(list, struct nodeinfo, write_list); |
998 | clear_bit(NI_WRITE_PENDING, &ni->flags); | 1001 | clear_bit(NI_WRITE_PENDING, &ni->flags); |
999 | list_del(&ni->write_list); | 1002 | list_del(&ni->write_list); |
1000 | 1003 | ||
@@ -1106,7 +1109,7 @@ static int dlm_recvd(void *data) | |||
1106 | set_current_state(TASK_INTERRUPTIBLE); | 1109 | set_current_state(TASK_INTERRUPTIBLE); |
1107 | add_wait_queue(&lowcomms_recv_wait, &wait); | 1110 | add_wait_queue(&lowcomms_recv_wait, &wait); |
1108 | if (!test_bit(CF_READ_PENDING, &sctp_con.flags)) | 1111 | if (!test_bit(CF_READ_PENDING, &sctp_con.flags)) |
1109 | schedule(); | 1112 | cond_resched(); |
1110 | remove_wait_queue(&lowcomms_recv_wait, &wait); | 1113 | remove_wait_queue(&lowcomms_recv_wait, &wait); |
1111 | set_current_state(TASK_RUNNING); | 1114 | set_current_state(TASK_RUNNING); |
1112 | 1115 | ||
@@ -1118,12 +1121,12 @@ static int dlm_recvd(void *data) | |||
1118 | 1121 | ||
1119 | /* Don't starve out everyone else */ | 1122 | /* Don't starve out everyone else */ |
1120 | if (++count >= MAX_RX_MSG_COUNT) { | 1123 | if (++count >= MAX_RX_MSG_COUNT) { |
1121 | schedule(); | 1124 | cond_resched(); |
1122 | count = 0; | 1125 | count = 0; |
1123 | } | 1126 | } |
1124 | } while (!kthread_should_stop() && ret >=0); | 1127 | } while (!kthread_should_stop() && ret >=0); |
1125 | } | 1128 | } |
1126 | schedule(); | 1129 | cond_resched(); |
1127 | } | 1130 | } |
1128 | 1131 | ||
1129 | return 0; | 1132 | return 0; |
@@ -1138,7 +1141,7 @@ static int dlm_sendd(void *data) | |||
1138 | while (!kthread_should_stop()) { | 1141 | while (!kthread_should_stop()) { |
1139 | set_current_state(TASK_INTERRUPTIBLE); | 1142 | set_current_state(TASK_INTERRUPTIBLE); |
1140 | if (write_list_empty()) | 1143 | if (write_list_empty()) |
1141 | schedule(); | 1144 | cond_resched(); |
1142 | set_current_state(TASK_RUNNING); | 1145 | set_current_state(TASK_RUNNING); |
1143 | 1146 | ||
1144 | if (sctp_con.eagain_flag) { | 1147 | if (sctp_con.eagain_flag) { |
@@ -1166,7 +1169,7 @@ static int daemons_start(void) | |||
1166 | 1169 | ||
1167 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); | 1170 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); |
1168 | error = IS_ERR(p); | 1171 | error = IS_ERR(p); |
1169 | if (error) { | 1172 | if (error) { |
1170 | log_print("can't start dlm_recvd %d", error); | 1173 | log_print("can't start dlm_recvd %d", error); |
1171 | return error; | 1174 | return error; |
1172 | } | 1175 | } |
@@ -1174,7 +1177,7 @@ static int daemons_start(void) | |||
1174 | 1177 | ||
1175 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); | 1178 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); |
1176 | error = IS_ERR(p); | 1179 | error = IS_ERR(p); |
1177 | if (error) { | 1180 | if (error) { |
1178 | log_print("can't start dlm_sendd %d", error); | 1181 | log_print("can't start dlm_sendd %d", error); |
1179 | kthread_stop(recv_task); | 1182 | kthread_stop(recv_task); |
1180 | return error; | 1183 | return error; |
@@ -1197,43 +1200,28 @@ int dlm_lowcomms_start(void) | |||
1197 | error = daemons_start(); | 1200 | error = daemons_start(); |
1198 | if (error) | 1201 | if (error) |
1199 | goto fail_sock; | 1202 | goto fail_sock; |
1200 | atomic_set(&accepting, 1); | ||
1201 | return 0; | 1203 | return 0; |
1202 | 1204 | ||
1203 | fail_sock: | 1205 | fail_sock: |
1204 | close_connection(); | 1206 | close_connection(); |
1205 | return error; | 1207 | return error; |
1206 | } | 1208 | } |
1207 | 1209 | ||
1208 | /* Set all the activity flags to prevent any socket activity. */ | ||
1209 | |||
1210 | void dlm_lowcomms_stop(void) | 1210 | void dlm_lowcomms_stop(void) |
1211 | { | 1211 | { |
1212 | atomic_set(&accepting, 0); | 1212 | int i; |
1213 | |||
1213 | sctp_con.flags = 0x7; | 1214 | sctp_con.flags = 0x7; |
1214 | daemons_stop(); | 1215 | daemons_stop(); |
1215 | clean_writequeues(); | 1216 | clean_writequeues(); |
1216 | close_connection(); | 1217 | close_connection(); |
1217 | dealloc_nodeinfo(); | 1218 | dealloc_nodeinfo(); |
1218 | max_nodeid = 0; | 1219 | max_nodeid = 0; |
1219 | } | ||
1220 | 1220 | ||
1221 | int dlm_lowcomms_init(void) | 1221 | dlm_local_count = 0; |
1222 | { | 1222 | dlm_local_nodeid = 0; |
1223 | init_waitqueue_head(&lowcomms_recv_wait); | ||
1224 | spin_lock_init(&write_nodes_lock); | ||
1225 | INIT_LIST_HEAD(&write_nodes); | ||
1226 | init_rwsem(&nodeinfo_lock); | ||
1227 | return 0; | ||
1228 | } | ||
1229 | |||
1230 | void dlm_lowcomms_exit(void) | ||
1231 | { | ||
1232 | int i; | ||
1233 | 1223 | ||
1234 | for (i = 0; i < dlm_local_count; i++) | 1224 | for (i = 0; i < dlm_local_count; i++) |
1235 | kfree(dlm_local_addr[i]); | 1225 | kfree(dlm_local_addr[i]); |
1236 | dlm_local_count = 0; | ||
1237 | dlm_local_nodeid = 0; | ||
1238 | } | 1226 | } |
1239 | 1227 | ||
diff --git a/fs/dlm/lowcomms-tcp.c b/fs/dlm/lowcomms-tcp.c new file mode 100644 index 000000000000..8f2791fc8447 --- /dev/null +++ b/fs/dlm/lowcomms-tcp.c | |||
@@ -0,0 +1,1189 @@ | |||
1 | /****************************************************************************** | ||
2 | ******************************************************************************* | ||
3 | ** | ||
4 | ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | ||
5 | ** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | ||
6 | ** | ||
7 | ** This copyrighted material is made available to anyone wishing to use, | ||
8 | ** modify, copy, or redistribute it subject to the terms and conditions | ||
9 | ** of the GNU General Public License v.2. | ||
10 | ** | ||
11 | ******************************************************************************* | ||
12 | ******************************************************************************/ | ||
13 | |||
14 | /* | ||
15 | * lowcomms.c | ||
16 | * | ||
17 | * This is the "low-level" comms layer. | ||
18 | * | ||
19 | * It is responsible for sending/receiving messages | ||
20 | * from other nodes in the cluster. | ||
21 | * | ||
22 | * Cluster nodes are referred to by their nodeids. nodeids are | ||
23 | * simply 32 bit numbers to the locking module - if they need to | ||
24 | * be expanded for the cluster infrastructure then that is it's | ||
25 | * responsibility. It is this layer's | ||
26 | * responsibility to resolve these into IP address or | ||
27 | * whatever it needs for inter-node communication. | ||
28 | * | ||
29 | * The comms level is two kernel threads that deal mainly with | ||
30 | * the receiving of messages from other nodes and passing them | ||
31 | * up to the mid-level comms layer (which understands the | ||
32 | * message format) for execution by the locking core, and | ||
33 | * a send thread which does all the setting up of connections | ||
34 | * to remote nodes and the sending of data. Threads are not allowed | ||
35 | * to send their own data because it may cause them to wait in times | ||
36 | * of high load. Also, this way, the sending thread can collect together | ||
37 | * messages bound for one node and send them in one block. | ||
38 | * | ||
39 | * I don't see any problem with the recv thread executing the locking | ||
40 | * code on behalf of remote processes as the locking code is | ||
41 | * short, efficient and never waits. | ||
42 | * | ||
43 | */ | ||
44 | |||
45 | |||
46 | #include <asm/ioctls.h> | ||
47 | #include <net/sock.h> | ||
48 | #include <net/tcp.h> | ||
49 | #include <linux/pagemap.h> | ||
50 | |||
51 | #include "dlm_internal.h" | ||
52 | #include "lowcomms.h" | ||
53 | #include "midcomms.h" | ||
54 | #include "config.h" | ||
55 | |||
56 | struct cbuf { | ||
57 | unsigned int base; | ||
58 | unsigned int len; | ||
59 | unsigned int mask; | ||
60 | }; | ||
61 | |||
62 | #define NODE_INCREMENT 32 | ||
63 | static void cbuf_add(struct cbuf *cb, int n) | ||
64 | { | ||
65 | cb->len += n; | ||
66 | } | ||
67 | |||
68 | static int cbuf_data(struct cbuf *cb) | ||
69 | { | ||
70 | return ((cb->base + cb->len) & cb->mask); | ||
71 | } | ||
72 | |||
73 | static void cbuf_init(struct cbuf *cb, int size) | ||
74 | { | ||
75 | cb->base = cb->len = 0; | ||
76 | cb->mask = size-1; | ||
77 | } | ||
78 | |||
79 | static void cbuf_eat(struct cbuf *cb, int n) | ||
80 | { | ||
81 | cb->len -= n; | ||
82 | cb->base += n; | ||
83 | cb->base &= cb->mask; | ||
84 | } | ||
85 | |||
86 | static bool cbuf_empty(struct cbuf *cb) | ||
87 | { | ||
88 | return cb->len == 0; | ||
89 | } | ||
90 | |||
91 | /* Maximum number of incoming messages to process before | ||
92 | doing a cond_resched() | ||
93 | */ | ||
94 | #define MAX_RX_MSG_COUNT 25 | ||
95 | |||
96 | struct connection { | ||
97 | struct socket *sock; /* NULL if not connected */ | ||
98 | uint32_t nodeid; /* So we know who we are in the list */ | ||
99 | struct rw_semaphore sock_sem; /* Stop connect races */ | ||
100 | struct list_head read_list; /* On this list when ready for reading */ | ||
101 | struct list_head write_list; /* On this list when ready for writing */ | ||
102 | struct list_head state_list; /* On this list when ready to connect */ | ||
103 | unsigned long flags; /* bit 1,2 = We are on the read/write lists */ | ||
104 | #define CF_READ_PENDING 1 | ||
105 | #define CF_WRITE_PENDING 2 | ||
106 | #define CF_CONNECT_PENDING 3 | ||
107 | #define CF_IS_OTHERCON 4 | ||
108 | struct list_head writequeue; /* List of outgoing writequeue_entries */ | ||
109 | struct list_head listenlist; /* List of allocated listening sockets */ | ||
110 | spinlock_t writequeue_lock; | ||
111 | int (*rx_action) (struct connection *); /* What to do when active */ | ||
112 | struct page *rx_page; | ||
113 | struct cbuf cb; | ||
114 | int retries; | ||
115 | atomic_t waiting_requests; | ||
116 | #define MAX_CONNECT_RETRIES 3 | ||
117 | struct connection *othercon; | ||
118 | }; | ||
119 | #define sock2con(x) ((struct connection *)(x)->sk_user_data) | ||
120 | |||
121 | /* An entry waiting to be sent */ | ||
122 | struct writequeue_entry { | ||
123 | struct list_head list; | ||
124 | struct page *page; | ||
125 | int offset; | ||
126 | int len; | ||
127 | int end; | ||
128 | int users; | ||
129 | struct connection *con; | ||
130 | }; | ||
131 | |||
132 | static struct sockaddr_storage dlm_local_addr; | ||
133 | |||
134 | /* Manage daemons */ | ||
135 | static struct task_struct *recv_task; | ||
136 | static struct task_struct *send_task; | ||
137 | |||
138 | static wait_queue_t lowcomms_send_waitq_head; | ||
139 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_send_waitq); | ||
140 | static wait_queue_t lowcomms_recv_waitq_head; | ||
141 | static DECLARE_WAIT_QUEUE_HEAD(lowcomms_recv_waitq); | ||
142 | |||
143 | /* An array of pointers to connections, indexed by NODEID */ | ||
144 | static struct connection **connections; | ||
145 | static DECLARE_MUTEX(connections_lock); | ||
146 | static kmem_cache_t *con_cache; | ||
147 | static int conn_array_size; | ||
148 | |||
149 | /* List of sockets that have reads pending */ | ||
150 | static LIST_HEAD(read_sockets); | ||
151 | static DEFINE_SPINLOCK(read_sockets_lock); | ||
152 | |||
153 | /* List of sockets which have writes pending */ | ||
154 | static LIST_HEAD(write_sockets); | ||
155 | static DEFINE_SPINLOCK(write_sockets_lock); | ||
156 | |||
157 | /* List of sockets which have connects pending */ | ||
158 | static LIST_HEAD(state_sockets); | ||
159 | static DEFINE_SPINLOCK(state_sockets_lock); | ||
160 | |||
161 | static struct connection *nodeid2con(int nodeid, gfp_t allocation) | ||
162 | { | ||
163 | struct connection *con = NULL; | ||
164 | |||
165 | down(&connections_lock); | ||
166 | if (nodeid >= conn_array_size) { | ||
167 | int new_size = nodeid + NODE_INCREMENT; | ||
168 | struct connection **new_conns; | ||
169 | |||
170 | new_conns = kzalloc(sizeof(struct connection *) * | ||
171 | new_size, allocation); | ||
172 | if (!new_conns) | ||
173 | goto finish; | ||
174 | |||
175 | memcpy(new_conns, connections, sizeof(struct connection *) * conn_array_size); | ||
176 | conn_array_size = new_size; | ||
177 | kfree(connections); | ||
178 | connections = new_conns; | ||
179 | |||
180 | } | ||
181 | |||
182 | con = connections[nodeid]; | ||
183 | if (con == NULL && allocation) { | ||
184 | con = kmem_cache_zalloc(con_cache, allocation); | ||
185 | if (!con) | ||
186 | goto finish; | ||
187 | |||
188 | con->nodeid = nodeid; | ||
189 | init_rwsem(&con->sock_sem); | ||
190 | INIT_LIST_HEAD(&con->writequeue); | ||
191 | spin_lock_init(&con->writequeue_lock); | ||
192 | |||
193 | connections[nodeid] = con; | ||
194 | } | ||
195 | |||
196 | finish: | ||
197 | up(&connections_lock); | ||
198 | return con; | ||
199 | } | ||
200 | |||
201 | /* Data available on socket or listen socket received a connect */ | ||
202 | static void lowcomms_data_ready(struct sock *sk, int count_unused) | ||
203 | { | ||
204 | struct connection *con = sock2con(sk); | ||
205 | |||
206 | atomic_inc(&con->waiting_requests); | ||
207 | if (test_and_set_bit(CF_READ_PENDING, &con->flags)) | ||
208 | return; | ||
209 | |||
210 | spin_lock_bh(&read_sockets_lock); | ||
211 | list_add_tail(&con->read_list, &read_sockets); | ||
212 | spin_unlock_bh(&read_sockets_lock); | ||
213 | |||
214 | wake_up_interruptible(&lowcomms_recv_waitq); | ||
215 | } | ||
216 | |||
217 | static void lowcomms_write_space(struct sock *sk) | ||
218 | { | ||
219 | struct connection *con = sock2con(sk); | ||
220 | |||
221 | if (test_and_set_bit(CF_WRITE_PENDING, &con->flags)) | ||
222 | return; | ||
223 | |||
224 | spin_lock_bh(&write_sockets_lock); | ||
225 | list_add_tail(&con->write_list, &write_sockets); | ||
226 | spin_unlock_bh(&write_sockets_lock); | ||
227 | |||
228 | wake_up_interruptible(&lowcomms_send_waitq); | ||
229 | } | ||
230 | |||
231 | static inline void lowcomms_connect_sock(struct connection *con) | ||
232 | { | ||
233 | if (test_and_set_bit(CF_CONNECT_PENDING, &con->flags)) | ||
234 | return; | ||
235 | |||
236 | spin_lock_bh(&state_sockets_lock); | ||
237 | list_add_tail(&con->state_list, &state_sockets); | ||
238 | spin_unlock_bh(&state_sockets_lock); | ||
239 | |||
240 | wake_up_interruptible(&lowcomms_send_waitq); | ||
241 | } | ||
242 | |||
243 | static void lowcomms_state_change(struct sock *sk) | ||
244 | { | ||
245 | if (sk->sk_state == TCP_ESTABLISHED) | ||
246 | lowcomms_write_space(sk); | ||
247 | } | ||
248 | |||
249 | /* Make a socket active */ | ||
250 | static int add_sock(struct socket *sock, struct connection *con) | ||
251 | { | ||
252 | con->sock = sock; | ||
253 | |||
254 | /* Install a data_ready callback */ | ||
255 | con->sock->sk->sk_data_ready = lowcomms_data_ready; | ||
256 | con->sock->sk->sk_write_space = lowcomms_write_space; | ||
257 | con->sock->sk->sk_state_change = lowcomms_state_change; | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | /* Add the port number to an IP6 or 4 sockaddr and return the address | ||
263 | length */ | ||
264 | static void make_sockaddr(struct sockaddr_storage *saddr, uint16_t port, | ||
265 | int *addr_len) | ||
266 | { | ||
267 | saddr->ss_family = dlm_local_addr.ss_family; | ||
268 | if (saddr->ss_family == AF_INET) { | ||
269 | struct sockaddr_in *in4_addr = (struct sockaddr_in *)saddr; | ||
270 | in4_addr->sin_port = cpu_to_be16(port); | ||
271 | *addr_len = sizeof(struct sockaddr_in); | ||
272 | } else { | ||
273 | struct sockaddr_in6 *in6_addr = (struct sockaddr_in6 *)saddr; | ||
274 | in6_addr->sin6_port = cpu_to_be16(port); | ||
275 | *addr_len = sizeof(struct sockaddr_in6); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | /* Close a remote connection and tidy up */ | ||
280 | static void close_connection(struct connection *con, bool and_other) | ||
281 | { | ||
282 | down_write(&con->sock_sem); | ||
283 | |||
284 | if (con->sock) { | ||
285 | sock_release(con->sock); | ||
286 | con->sock = NULL; | ||
287 | } | ||
288 | if (con->othercon && and_other) { | ||
289 | /* Will only re-enter once. */ | ||
290 | close_connection(con->othercon, false); | ||
291 | } | ||
292 | if (con->rx_page) { | ||
293 | __free_page(con->rx_page); | ||
294 | con->rx_page = NULL; | ||
295 | } | ||
296 | con->retries = 0; | ||
297 | up_write(&con->sock_sem); | ||
298 | } | ||
299 | |||
300 | /* Data received from remote end */ | ||
301 | static int receive_from_sock(struct connection *con) | ||
302 | { | ||
303 | int ret = 0; | ||
304 | struct msghdr msg; | ||
305 | struct iovec iov[2]; | ||
306 | mm_segment_t fs; | ||
307 | unsigned len; | ||
308 | int r; | ||
309 | int call_again_soon = 0; | ||
310 | |||
311 | down_read(&con->sock_sem); | ||
312 | |||
313 | if (con->sock == NULL) | ||
314 | goto out; | ||
315 | if (con->rx_page == NULL) { | ||
316 | /* | ||
317 | * This doesn't need to be atomic, but I think it should | ||
318 | * improve performance if it is. | ||
319 | */ | ||
320 | con->rx_page = alloc_page(GFP_ATOMIC); | ||
321 | if (con->rx_page == NULL) | ||
322 | goto out_resched; | ||
323 | cbuf_init(&con->cb, PAGE_CACHE_SIZE); | ||
324 | } | ||
325 | |||
326 | msg.msg_control = NULL; | ||
327 | msg.msg_controllen = 0; | ||
328 | msg.msg_iovlen = 1; | ||
329 | msg.msg_iov = iov; | ||
330 | msg.msg_name = NULL; | ||
331 | msg.msg_namelen = 0; | ||
332 | msg.msg_flags = 0; | ||
333 | |||
334 | /* | ||
335 | * iov[0] is the bit of the circular buffer between the current end | ||
336 | * point (cb.base + cb.len) and the end of the buffer. | ||
337 | */ | ||
338 | iov[0].iov_len = con->cb.base - cbuf_data(&con->cb); | ||
339 | iov[0].iov_base = page_address(con->rx_page) + cbuf_data(&con->cb); | ||
340 | iov[1].iov_len = 0; | ||
341 | |||
342 | /* | ||
343 | * iov[1] is the bit of the circular buffer between the start of the | ||
344 | * buffer and the start of the currently used section (cb.base) | ||
345 | */ | ||
346 | if (cbuf_data(&con->cb) >= con->cb.base) { | ||
347 | iov[0].iov_len = PAGE_CACHE_SIZE - cbuf_data(&con->cb); | ||
348 | iov[1].iov_len = con->cb.base; | ||
349 | iov[1].iov_base = page_address(con->rx_page); | ||
350 | msg.msg_iovlen = 2; | ||
351 | } | ||
352 | len = iov[0].iov_len + iov[1].iov_len; | ||
353 | |||
354 | fs = get_fs(); | ||
355 | set_fs(get_ds()); | ||
356 | r = ret = sock_recvmsg(con->sock, &msg, len, | ||
357 | MSG_DONTWAIT | MSG_NOSIGNAL); | ||
358 | set_fs(fs); | ||
359 | |||
360 | if (ret <= 0) | ||
361 | goto out_close; | ||
362 | if (ret == len) | ||
363 | call_again_soon = 1; | ||
364 | cbuf_add(&con->cb, ret); | ||
365 | ret = dlm_process_incoming_buffer(con->nodeid, | ||
366 | page_address(con->rx_page), | ||
367 | con->cb.base, con->cb.len, | ||
368 | PAGE_CACHE_SIZE); | ||
369 | if (ret == -EBADMSG) { | ||
370 | printk(KERN_INFO "dlm: lowcomms: addr=%p, base=%u, len=%u, " | ||
371 | "iov_len=%u, iov_base[0]=%p, read=%d\n", | ||
372 | page_address(con->rx_page), con->cb.base, con->cb.len, | ||
373 | len, iov[0].iov_base, r); | ||
374 | } | ||
375 | if (ret < 0) | ||
376 | goto out_close; | ||
377 | cbuf_eat(&con->cb, ret); | ||
378 | |||
379 | if (cbuf_empty(&con->cb) && !call_again_soon) { | ||
380 | __free_page(con->rx_page); | ||
381 | con->rx_page = NULL; | ||
382 | } | ||
383 | |||
384 | out: | ||
385 | if (call_again_soon) | ||
386 | goto out_resched; | ||
387 | up_read(&con->sock_sem); | ||
388 | return 0; | ||
389 | |||
390 | out_resched: | ||
391 | lowcomms_data_ready(con->sock->sk, 0); | ||
392 | up_read(&con->sock_sem); | ||
393 | cond_resched(); | ||
394 | return 0; | ||
395 | |||
396 | out_close: | ||
397 | up_read(&con->sock_sem); | ||
398 | if (ret != -EAGAIN && !test_bit(CF_IS_OTHERCON, &con->flags)) { | ||
399 | close_connection(con, false); | ||
400 | /* Reconnect when there is something to send */ | ||
401 | } | ||
402 | |||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | /* Listening socket is busy, accept a connection */ | ||
407 | static int accept_from_sock(struct connection *con) | ||
408 | { | ||
409 | int result; | ||
410 | struct sockaddr_storage peeraddr; | ||
411 | struct socket *newsock; | ||
412 | int len; | ||
413 | int nodeid; | ||
414 | struct connection *newcon; | ||
415 | |||
416 | memset(&peeraddr, 0, sizeof(peeraddr)); | ||
417 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, | ||
418 | IPPROTO_TCP, &newsock); | ||
419 | if (result < 0) | ||
420 | return -ENOMEM; | ||
421 | |||
422 | down_read(&con->sock_sem); | ||
423 | |||
424 | result = -ENOTCONN; | ||
425 | if (con->sock == NULL) | ||
426 | goto accept_err; | ||
427 | |||
428 | newsock->type = con->sock->type; | ||
429 | newsock->ops = con->sock->ops; | ||
430 | |||
431 | result = con->sock->ops->accept(con->sock, newsock, O_NONBLOCK); | ||
432 | if (result < 0) | ||
433 | goto accept_err; | ||
434 | |||
435 | /* Get the connected socket's peer */ | ||
436 | memset(&peeraddr, 0, sizeof(peeraddr)); | ||
437 | if (newsock->ops->getname(newsock, (struct sockaddr *)&peeraddr, | ||
438 | &len, 2)) { | ||
439 | result = -ECONNABORTED; | ||
440 | goto accept_err; | ||
441 | } | ||
442 | |||
443 | /* Get the new node's NODEID */ | ||
444 | make_sockaddr(&peeraddr, 0, &len); | ||
445 | if (dlm_addr_to_nodeid(&peeraddr, &nodeid)) { | ||
446 | printk("dlm: connect from non cluster node\n"); | ||
447 | sock_release(newsock); | ||
448 | up_read(&con->sock_sem); | ||
449 | return -1; | ||
450 | } | ||
451 | |||
452 | log_print("got connection from %d", nodeid); | ||
453 | |||
454 | /* Check to see if we already have a connection to this node. This | ||
455 | * could happen if the two nodes initiate a connection at roughly | ||
456 | * the same time and the connections cross on the wire. | ||
457 | * TEMPORARY FIX: | ||
458 | * In this case we store the incoming one in "othercon" | ||
459 | */ | ||
460 | newcon = nodeid2con(nodeid, GFP_KERNEL); | ||
461 | if (!newcon) { | ||
462 | result = -ENOMEM; | ||
463 | goto accept_err; | ||
464 | } | ||
465 | down_write(&newcon->sock_sem); | ||
466 | if (newcon->sock) { | ||
467 | struct connection *othercon = newcon->othercon; | ||
468 | |||
469 | if (!othercon) { | ||
470 | othercon = kmem_cache_zalloc(con_cache, GFP_KERNEL); | ||
471 | if (!othercon) { | ||
472 | printk("dlm: failed to allocate incoming socket\n"); | ||
473 | up_write(&newcon->sock_sem); | ||
474 | result = -ENOMEM; | ||
475 | goto accept_err; | ||
476 | } | ||
477 | othercon->nodeid = nodeid; | ||
478 | othercon->rx_action = receive_from_sock; | ||
479 | init_rwsem(&othercon->sock_sem); | ||
480 | set_bit(CF_IS_OTHERCON, &othercon->flags); | ||
481 | newcon->othercon = othercon; | ||
482 | } | ||
483 | othercon->sock = newsock; | ||
484 | newsock->sk->sk_user_data = othercon; | ||
485 | add_sock(newsock, othercon); | ||
486 | } | ||
487 | else { | ||
488 | newsock->sk->sk_user_data = newcon; | ||
489 | newcon->rx_action = receive_from_sock; | ||
490 | add_sock(newsock, newcon); | ||
491 | |||
492 | } | ||
493 | |||
494 | up_write(&newcon->sock_sem); | ||
495 | |||
496 | /* | ||
497 | * Add it to the active queue in case we got data | ||
498 | * beween processing the accept adding the socket | ||
499 | * to the read_sockets list | ||
500 | */ | ||
501 | lowcomms_data_ready(newsock->sk, 0); | ||
502 | up_read(&con->sock_sem); | ||
503 | |||
504 | return 0; | ||
505 | |||
506 | accept_err: | ||
507 | up_read(&con->sock_sem); | ||
508 | sock_release(newsock); | ||
509 | |||
510 | if (result != -EAGAIN) | ||
511 | printk("dlm: error accepting connection from node: %d\n", result); | ||
512 | return result; | ||
513 | } | ||
514 | |||
515 | /* Connect a new socket to its peer */ | ||
516 | static void connect_to_sock(struct connection *con) | ||
517 | { | ||
518 | int result = -EHOSTUNREACH; | ||
519 | struct sockaddr_storage saddr; | ||
520 | int addr_len; | ||
521 | struct socket *sock; | ||
522 | |||
523 | if (con->nodeid == 0) { | ||
524 | log_print("attempt to connect sock 0 foiled"); | ||
525 | return; | ||
526 | } | ||
527 | |||
528 | down_write(&con->sock_sem); | ||
529 | if (con->retries++ > MAX_CONNECT_RETRIES) | ||
530 | goto out; | ||
531 | |||
532 | /* Some odd races can cause double-connects, ignore them */ | ||
533 | if (con->sock) { | ||
534 | result = 0; | ||
535 | goto out; | ||
536 | } | ||
537 | |||
538 | /* Create a socket to communicate with */ | ||
539 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, | ||
540 | IPPROTO_TCP, &sock); | ||
541 | if (result < 0) | ||
542 | goto out_err; | ||
543 | |||
544 | memset(&saddr, 0, sizeof(saddr)); | ||
545 | if (dlm_nodeid_to_addr(con->nodeid, &saddr)) | ||
546 | goto out_err; | ||
547 | |||
548 | sock->sk->sk_user_data = con; | ||
549 | con->rx_action = receive_from_sock; | ||
550 | |||
551 | make_sockaddr(&saddr, dlm_config.tcp_port, &addr_len); | ||
552 | |||
553 | add_sock(sock, con); | ||
554 | |||
555 | log_print("connecting to %d", con->nodeid); | ||
556 | result = | ||
557 | sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, | ||
558 | O_NONBLOCK); | ||
559 | if (result == -EINPROGRESS) | ||
560 | result = 0; | ||
561 | if (result == 0) | ||
562 | goto out; | ||
563 | |||
564 | out_err: | ||
565 | if (con->sock) { | ||
566 | sock_release(con->sock); | ||
567 | con->sock = NULL; | ||
568 | } | ||
569 | /* | ||
570 | * Some errors are fatal and this list might need adjusting. For other | ||
571 | * errors we try again until the max number of retries is reached. | ||
572 | */ | ||
573 | if (result != -EHOSTUNREACH && result != -ENETUNREACH && | ||
574 | result != -ENETDOWN && result != EINVAL | ||
575 | && result != -EPROTONOSUPPORT) { | ||
576 | lowcomms_connect_sock(con); | ||
577 | result = 0; | ||
578 | } | ||
579 | out: | ||
580 | up_write(&con->sock_sem); | ||
581 | return; | ||
582 | } | ||
583 | |||
584 | static struct socket *create_listen_sock(struct connection *con, | ||
585 | struct sockaddr_storage *saddr) | ||
586 | { | ||
587 | struct socket *sock = NULL; | ||
588 | mm_segment_t fs; | ||
589 | int result = 0; | ||
590 | int one = 1; | ||
591 | int addr_len; | ||
592 | |||
593 | if (dlm_local_addr.ss_family == AF_INET) | ||
594 | addr_len = sizeof(struct sockaddr_in); | ||
595 | else | ||
596 | addr_len = sizeof(struct sockaddr_in6); | ||
597 | |||
598 | /* Create a socket to communicate with */ | ||
599 | result = sock_create_kern(dlm_local_addr.ss_family, SOCK_STREAM, IPPROTO_TCP, &sock); | ||
600 | if (result < 0) { | ||
601 | printk("dlm: Can't create listening comms socket\n"); | ||
602 | goto create_out; | ||
603 | } | ||
604 | |||
605 | fs = get_fs(); | ||
606 | set_fs(get_ds()); | ||
607 | result = sock_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, | ||
608 | (char *)&one, sizeof(one)); | ||
609 | set_fs(fs); | ||
610 | if (result < 0) { | ||
611 | printk("dlm: Failed to set SO_REUSEADDR on socket: result=%d\n", | ||
612 | result); | ||
613 | } | ||
614 | sock->sk->sk_user_data = con; | ||
615 | con->rx_action = accept_from_sock; | ||
616 | con->sock = sock; | ||
617 | |||
618 | /* Bind to our port */ | ||
619 | make_sockaddr(saddr, dlm_config.tcp_port, &addr_len); | ||
620 | result = sock->ops->bind(sock, (struct sockaddr *) saddr, addr_len); | ||
621 | if (result < 0) { | ||
622 | printk("dlm: Can't bind to port %d\n", dlm_config.tcp_port); | ||
623 | sock_release(sock); | ||
624 | sock = NULL; | ||
625 | con->sock = NULL; | ||
626 | goto create_out; | ||
627 | } | ||
628 | |||
629 | fs = get_fs(); | ||
630 | set_fs(get_ds()); | ||
631 | |||
632 | result = sock_setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, | ||
633 | (char *)&one, sizeof(one)); | ||
634 | set_fs(fs); | ||
635 | if (result < 0) { | ||
636 | printk("dlm: Set keepalive failed: %d\n", result); | ||
637 | } | ||
638 | |||
639 | result = sock->ops->listen(sock, 5); | ||
640 | if (result < 0) { | ||
641 | printk("dlm: Can't listen on port %d\n", dlm_config.tcp_port); | ||
642 | sock_release(sock); | ||
643 | sock = NULL; | ||
644 | goto create_out; | ||
645 | } | ||
646 | |||
647 | create_out: | ||
648 | return sock; | ||
649 | } | ||
650 | |||
651 | |||
652 | /* Listen on all interfaces */ | ||
653 | static int listen_for_all(void) | ||
654 | { | ||
655 | struct socket *sock = NULL; | ||
656 | struct connection *con = nodeid2con(0, GFP_KERNEL); | ||
657 | int result = -EINVAL; | ||
658 | |||
659 | /* We don't support multi-homed hosts */ | ||
660 | set_bit(CF_IS_OTHERCON, &con->flags); | ||
661 | |||
662 | sock = create_listen_sock(con, &dlm_local_addr); | ||
663 | if (sock) { | ||
664 | add_sock(sock, con); | ||
665 | result = 0; | ||
666 | } | ||
667 | else { | ||
668 | result = -EADDRINUSE; | ||
669 | } | ||
670 | |||
671 | return result; | ||
672 | } | ||
673 | |||
674 | |||
675 | |||
676 | static struct writequeue_entry *new_writequeue_entry(struct connection *con, | ||
677 | gfp_t allocation) | ||
678 | { | ||
679 | struct writequeue_entry *entry; | ||
680 | |||
681 | entry = kmalloc(sizeof(struct writequeue_entry), allocation); | ||
682 | if (!entry) | ||
683 | return NULL; | ||
684 | |||
685 | entry->page = alloc_page(allocation); | ||
686 | if (!entry->page) { | ||
687 | kfree(entry); | ||
688 | return NULL; | ||
689 | } | ||
690 | |||
691 | entry->offset = 0; | ||
692 | entry->len = 0; | ||
693 | entry->end = 0; | ||
694 | entry->users = 0; | ||
695 | entry->con = con; | ||
696 | |||
697 | return entry; | ||
698 | } | ||
699 | |||
700 | void *dlm_lowcomms_get_buffer(int nodeid, int len, | ||
701 | gfp_t allocation, char **ppc) | ||
702 | { | ||
703 | struct connection *con; | ||
704 | struct writequeue_entry *e; | ||
705 | int offset = 0; | ||
706 | int users = 0; | ||
707 | |||
708 | con = nodeid2con(nodeid, allocation); | ||
709 | if (!con) | ||
710 | return NULL; | ||
711 | |||
712 | e = list_entry(con->writequeue.prev, struct writequeue_entry, list); | ||
713 | if ((&e->list == &con->writequeue) || | ||
714 | (PAGE_CACHE_SIZE - e->end < len)) { | ||
715 | e = NULL; | ||
716 | } else { | ||
717 | offset = e->end; | ||
718 | e->end += len; | ||
719 | users = e->users++; | ||
720 | } | ||
721 | spin_unlock(&con->writequeue_lock); | ||
722 | |||
723 | if (e) { | ||
724 | got_one: | ||
725 | if (users == 0) | ||
726 | kmap(e->page); | ||
727 | *ppc = page_address(e->page) + offset; | ||
728 | return e; | ||
729 | } | ||
730 | |||
731 | e = new_writequeue_entry(con, allocation); | ||
732 | if (e) { | ||
733 | spin_lock(&con->writequeue_lock); | ||
734 | offset = e->end; | ||
735 | e->end += len; | ||
736 | users = e->users++; | ||
737 | list_add_tail(&e->list, &con->writequeue); | ||
738 | spin_unlock(&con->writequeue_lock); | ||
739 | goto got_one; | ||
740 | } | ||
741 | return NULL; | ||
742 | } | ||
743 | |||
744 | void dlm_lowcomms_commit_buffer(void *mh) | ||
745 | { | ||
746 | struct writequeue_entry *e = (struct writequeue_entry *)mh; | ||
747 | struct connection *con = e->con; | ||
748 | int users; | ||
749 | |||
750 | users = --e->users; | ||
751 | if (users) | ||
752 | goto out; | ||
753 | e->len = e->end - e->offset; | ||
754 | kunmap(e->page); | ||
755 | spin_unlock(&con->writequeue_lock); | ||
756 | |||
757 | if (test_and_set_bit(CF_WRITE_PENDING, &con->flags) == 0) { | ||
758 | spin_lock_bh(&write_sockets_lock); | ||
759 | list_add_tail(&con->write_list, &write_sockets); | ||
760 | spin_unlock_bh(&write_sockets_lock); | ||
761 | |||
762 | wake_up_interruptible(&lowcomms_send_waitq); | ||
763 | } | ||
764 | return; | ||
765 | |||
766 | out: | ||
767 | spin_unlock(&con->writequeue_lock); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | static void free_entry(struct writequeue_entry *e) | ||
772 | { | ||
773 | __free_page(e->page); | ||
774 | kfree(e); | ||
775 | } | ||
776 | |||
777 | /* Send a message */ | ||
778 | static void send_to_sock(struct connection *con) | ||
779 | { | ||
780 | int ret = 0; | ||
781 | ssize_t(*sendpage) (struct socket *, struct page *, int, size_t, int); | ||
782 | const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; | ||
783 | struct writequeue_entry *e; | ||
784 | int len, offset; | ||
785 | |||
786 | down_read(&con->sock_sem); | ||
787 | if (con->sock == NULL) | ||
788 | goto out_connect; | ||
789 | |||
790 | sendpage = con->sock->ops->sendpage; | ||
791 | |||
792 | spin_lock(&con->writequeue_lock); | ||
793 | for (;;) { | ||
794 | e = list_entry(con->writequeue.next, struct writequeue_entry, | ||
795 | list); | ||
796 | if ((struct list_head *) e == &con->writequeue) | ||
797 | break; | ||
798 | |||
799 | len = e->len; | ||
800 | offset = e->offset; | ||
801 | BUG_ON(len == 0 && e->users == 0); | ||
802 | spin_unlock(&con->writequeue_lock); | ||
803 | |||
804 | ret = 0; | ||
805 | if (len) { | ||
806 | ret = sendpage(con->sock, e->page, offset, len, | ||
807 | msg_flags); | ||
808 | if (ret == -EAGAIN || ret == 0) | ||
809 | goto out; | ||
810 | if (ret <= 0) | ||
811 | goto send_error; | ||
812 | } | ||
813 | else { | ||
814 | /* Don't starve people filling buffers */ | ||
815 | cond_resched(); | ||
816 | } | ||
817 | |||
818 | spin_lock(&con->writequeue_lock); | ||
819 | e->offset += ret; | ||
820 | e->len -= ret; | ||
821 | |||
822 | if (e->len == 0 && e->users == 0) { | ||
823 | list_del(&e->list); | ||
824 | kunmap(e->page); | ||
825 | free_entry(e); | ||
826 | continue; | ||
827 | } | ||
828 | } | ||
829 | spin_unlock(&con->writequeue_lock); | ||
830 | out: | ||
831 | up_read(&con->sock_sem); | ||
832 | return; | ||
833 | |||
834 | send_error: | ||
835 | up_read(&con->sock_sem); | ||
836 | close_connection(con, false); | ||
837 | lowcomms_connect_sock(con); | ||
838 | return; | ||
839 | |||
840 | out_connect: | ||
841 | up_read(&con->sock_sem); | ||
842 | lowcomms_connect_sock(con); | ||
843 | return; | ||
844 | } | ||
845 | |||
846 | static void clean_one_writequeue(struct connection *con) | ||
847 | { | ||
848 | struct list_head *list; | ||
849 | struct list_head *temp; | ||
850 | |||
851 | spin_lock(&con->writequeue_lock); | ||
852 | list_for_each_safe(list, temp, &con->writequeue) { | ||
853 | struct writequeue_entry *e = | ||
854 | list_entry(list, struct writequeue_entry, list); | ||
855 | list_del(&e->list); | ||
856 | free_entry(e); | ||
857 | } | ||
858 | spin_unlock(&con->writequeue_lock); | ||
859 | } | ||
860 | |||
861 | /* Called from recovery when it knows that a node has | ||
862 | left the cluster */ | ||
863 | int dlm_lowcomms_close(int nodeid) | ||
864 | { | ||
865 | struct connection *con; | ||
866 | |||
867 | if (!connections) | ||
868 | goto out; | ||
869 | |||
870 | log_print("closing connection to node %d", nodeid); | ||
871 | con = nodeid2con(nodeid, 0); | ||
872 | if (con) { | ||
873 | clean_one_writequeue(con); | ||
874 | close_connection(con, true); | ||
875 | atomic_set(&con->waiting_requests, 0); | ||
876 | } | ||
877 | return 0; | ||
878 | |||
879 | out: | ||
880 | return -1; | ||
881 | } | ||
882 | |||
883 | /* API send message call, may queue the request */ | ||
884 | /* N.B. This is the old interface - use the new one for new calls */ | ||
885 | int lowcomms_send_message(int nodeid, char *buf, int len, gfp_t allocation) | ||
886 | { | ||
887 | struct writequeue_entry *e; | ||
888 | char *b; | ||
889 | |||
890 | e = dlm_lowcomms_get_buffer(nodeid, len, allocation, &b); | ||
891 | if (e) { | ||
892 | memcpy(b, buf, len); | ||
893 | dlm_lowcomms_commit_buffer(e); | ||
894 | return 0; | ||
895 | } | ||
896 | return -ENOBUFS; | ||
897 | } | ||
898 | |||
899 | /* Look for activity on active sockets */ | ||
900 | static void process_sockets(void) | ||
901 | { | ||
902 | struct list_head *list; | ||
903 | struct list_head *temp; | ||
904 | int count = 0; | ||
905 | |||
906 | spin_lock_bh(&read_sockets_lock); | ||
907 | list_for_each_safe(list, temp, &read_sockets) { | ||
908 | |||
909 | struct connection *con = | ||
910 | list_entry(list, struct connection, read_list); | ||
911 | list_del(&con->read_list); | ||
912 | clear_bit(CF_READ_PENDING, &con->flags); | ||
913 | |||
914 | spin_unlock_bh(&read_sockets_lock); | ||
915 | |||
916 | /* This can reach zero if we are processing requests | ||
917 | * as they come in. | ||
918 | */ | ||
919 | if (atomic_read(&con->waiting_requests) == 0) { | ||
920 | spin_lock_bh(&read_sockets_lock); | ||
921 | continue; | ||
922 | } | ||
923 | |||
924 | do { | ||
925 | con->rx_action(con); | ||
926 | |||
927 | /* Don't starve out everyone else */ | ||
928 | if (++count >= MAX_RX_MSG_COUNT) { | ||
929 | cond_resched(); | ||
930 | count = 0; | ||
931 | } | ||
932 | |||
933 | } while (!atomic_dec_and_test(&con->waiting_requests) && | ||
934 | !kthread_should_stop()); | ||
935 | |||
936 | spin_lock_bh(&read_sockets_lock); | ||
937 | } | ||
938 | spin_unlock_bh(&read_sockets_lock); | ||
939 | } | ||
940 | |||
941 | /* Try to send any messages that are pending | ||
942 | */ | ||
943 | static void process_output_queue(void) | ||
944 | { | ||
945 | struct list_head *list; | ||
946 | struct list_head *temp; | ||
947 | |||
948 | spin_lock_bh(&write_sockets_lock); | ||
949 | list_for_each_safe(list, temp, &write_sockets) { | ||
950 | struct connection *con = | ||
951 | list_entry(list, struct connection, write_list); | ||
952 | clear_bit(CF_WRITE_PENDING, &con->flags); | ||
953 | list_del(&con->write_list); | ||
954 | |||
955 | spin_unlock_bh(&write_sockets_lock); | ||
956 | send_to_sock(con); | ||
957 | spin_lock_bh(&write_sockets_lock); | ||
958 | } | ||
959 | spin_unlock_bh(&write_sockets_lock); | ||
960 | } | ||
961 | |||
962 | static void process_state_queue(void) | ||
963 | { | ||
964 | struct list_head *list; | ||
965 | struct list_head *temp; | ||
966 | |||
967 | spin_lock_bh(&state_sockets_lock); | ||
968 | list_for_each_safe(list, temp, &state_sockets) { | ||
969 | struct connection *con = | ||
970 | list_entry(list, struct connection, state_list); | ||
971 | list_del(&con->state_list); | ||
972 | clear_bit(CF_CONNECT_PENDING, &con->flags); | ||
973 | spin_unlock_bh(&state_sockets_lock); | ||
974 | |||
975 | connect_to_sock(con); | ||
976 | spin_lock_bh(&state_sockets_lock); | ||
977 | } | ||
978 | spin_unlock_bh(&state_sockets_lock); | ||
979 | } | ||
980 | |||
981 | |||
982 | /* Discard all entries on the write queues */ | ||
983 | static void clean_writequeues(void) | ||
984 | { | ||
985 | int nodeid; | ||
986 | |||
987 | for (nodeid = 1; nodeid < conn_array_size; nodeid++) { | ||
988 | struct connection *con = nodeid2con(nodeid, 0); | ||
989 | |||
990 | if (con) | ||
991 | clean_one_writequeue(con); | ||
992 | } | ||
993 | } | ||
994 | |||
995 | static int read_list_empty(void) | ||
996 | { | ||
997 | int status; | ||
998 | |||
999 | spin_lock_bh(&read_sockets_lock); | ||
1000 | status = list_empty(&read_sockets); | ||
1001 | spin_unlock_bh(&read_sockets_lock); | ||
1002 | |||
1003 | return status; | ||
1004 | } | ||
1005 | |||
1006 | /* DLM Transport comms receive daemon */ | ||
1007 | static int dlm_recvd(void *data) | ||
1008 | { | ||
1009 | init_waitqueue_entry(&lowcomms_recv_waitq_head, current); | ||
1010 | add_wait_queue(&lowcomms_recv_waitq, &lowcomms_recv_waitq_head); | ||
1011 | |||
1012 | while (!kthread_should_stop()) { | ||
1013 | set_current_state(TASK_INTERRUPTIBLE); | ||
1014 | if (read_list_empty()) | ||
1015 | cond_resched(); | ||
1016 | set_current_state(TASK_RUNNING); | ||
1017 | |||
1018 | process_sockets(); | ||
1019 | } | ||
1020 | |||
1021 | return 0; | ||
1022 | } | ||
1023 | |||
1024 | static int write_and_state_lists_empty(void) | ||
1025 | { | ||
1026 | int status; | ||
1027 | |||
1028 | spin_lock_bh(&write_sockets_lock); | ||
1029 | status = list_empty(&write_sockets); | ||
1030 | spin_unlock_bh(&write_sockets_lock); | ||
1031 | |||
1032 | spin_lock_bh(&state_sockets_lock); | ||
1033 | if (list_empty(&state_sockets) == 0) | ||
1034 | status = 0; | ||
1035 | spin_unlock_bh(&state_sockets_lock); | ||
1036 | |||
1037 | return status; | ||
1038 | } | ||
1039 | |||
1040 | /* DLM Transport send daemon */ | ||
1041 | static int dlm_sendd(void *data) | ||
1042 | { | ||
1043 | init_waitqueue_entry(&lowcomms_send_waitq_head, current); | ||
1044 | add_wait_queue(&lowcomms_send_waitq, &lowcomms_send_waitq_head); | ||
1045 | |||
1046 | while (!kthread_should_stop()) { | ||
1047 | set_current_state(TASK_INTERRUPTIBLE); | ||
1048 | if (write_and_state_lists_empty()) | ||
1049 | cond_resched(); | ||
1050 | set_current_state(TASK_RUNNING); | ||
1051 | |||
1052 | process_state_queue(); | ||
1053 | process_output_queue(); | ||
1054 | } | ||
1055 | |||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | static void daemons_stop(void) | ||
1060 | { | ||
1061 | kthread_stop(recv_task); | ||
1062 | kthread_stop(send_task); | ||
1063 | } | ||
1064 | |||
1065 | static int daemons_start(void) | ||
1066 | { | ||
1067 | struct task_struct *p; | ||
1068 | int error; | ||
1069 | |||
1070 | p = kthread_run(dlm_recvd, NULL, "dlm_recvd"); | ||
1071 | error = IS_ERR(p); | ||
1072 | if (error) { | ||
1073 | log_print("can't start dlm_recvd %d", error); | ||
1074 | return error; | ||
1075 | } | ||
1076 | recv_task = p; | ||
1077 | |||
1078 | p = kthread_run(dlm_sendd, NULL, "dlm_sendd"); | ||
1079 | error = IS_ERR(p); | ||
1080 | if (error) { | ||
1081 | log_print("can't start dlm_sendd %d", error); | ||
1082 | kthread_stop(recv_task); | ||
1083 | return error; | ||
1084 | } | ||
1085 | send_task = p; | ||
1086 | |||
1087 | return 0; | ||
1088 | } | ||
1089 | |||
1090 | /* | ||
1091 | * Return the largest buffer size we can cope with. | ||
1092 | */ | ||
1093 | int lowcomms_max_buffer_size(void) | ||
1094 | { | ||
1095 | return PAGE_CACHE_SIZE; | ||
1096 | } | ||
1097 | |||
1098 | void dlm_lowcomms_stop(void) | ||
1099 | { | ||
1100 | int i; | ||
1101 | |||
1102 | /* Set all the flags to prevent any | ||
1103 | socket activity. | ||
1104 | */ | ||
1105 | for (i = 0; i < conn_array_size; i++) { | ||
1106 | if (connections[i]) | ||
1107 | connections[i]->flags |= 0xFF; | ||
1108 | } | ||
1109 | |||
1110 | daemons_stop(); | ||
1111 | clean_writequeues(); | ||
1112 | |||
1113 | for (i = 0; i < conn_array_size; i++) { | ||
1114 | if (connections[i]) { | ||
1115 | close_connection(connections[i], true); | ||
1116 | if (connections[i]->othercon) | ||
1117 | kmem_cache_free(con_cache, connections[i]->othercon); | ||
1118 | kmem_cache_free(con_cache, connections[i]); | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | kfree(connections); | ||
1123 | connections = NULL; | ||
1124 | |||
1125 | kmem_cache_destroy(con_cache); | ||
1126 | } | ||
1127 | |||
1128 | /* This is quite likely to sleep... */ | ||
1129 | int dlm_lowcomms_start(void) | ||
1130 | { | ||
1131 | int error = 0; | ||
1132 | |||
1133 | error = -ENOMEM; | ||
1134 | connections = kzalloc(sizeof(struct connection *) * | ||
1135 | NODE_INCREMENT, GFP_KERNEL); | ||
1136 | if (!connections) | ||
1137 | goto out; | ||
1138 | |||
1139 | conn_array_size = NODE_INCREMENT; | ||
1140 | |||
1141 | if (dlm_our_addr(&dlm_local_addr, 0)) { | ||
1142 | log_print("no local IP address has been set"); | ||
1143 | goto fail_free_conn; | ||
1144 | } | ||
1145 | if (!dlm_our_addr(&dlm_local_addr, 1)) { | ||
1146 | log_print("This dlm comms module does not support multi-homed clustering"); | ||
1147 | goto fail_free_conn; | ||
1148 | } | ||
1149 | |||
1150 | con_cache = kmem_cache_create("dlm_conn", sizeof(struct connection), | ||
1151 | __alignof__(struct connection), 0, | ||
1152 | NULL, NULL); | ||
1153 | if (!con_cache) | ||
1154 | goto fail_free_conn; | ||
1155 | |||
1156 | |||
1157 | /* Start listening */ | ||
1158 | error = listen_for_all(); | ||
1159 | if (error) | ||
1160 | goto fail_unlisten; | ||
1161 | |||
1162 | error = daemons_start(); | ||
1163 | if (error) | ||
1164 | goto fail_unlisten; | ||
1165 | |||
1166 | return 0; | ||
1167 | |||
1168 | fail_unlisten: | ||
1169 | close_connection(connections[0], false); | ||
1170 | kmem_cache_free(con_cache, connections[0]); | ||
1171 | kmem_cache_destroy(con_cache); | ||
1172 | |||
1173 | fail_free_conn: | ||
1174 | kfree(connections); | ||
1175 | |||
1176 | out: | ||
1177 | return error; | ||
1178 | } | ||
1179 | |||
1180 | /* | ||
1181 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
1182 | * Emacs will notice this stuff at the end of the file and automatically | ||
1183 | * adjust the settings for this buffer only. This must remain at the end | ||
1184 | * of the file. | ||
1185 | * --------------------------------------------------------------------------- | ||
1186 | * Local variables: | ||
1187 | * c-file-style: "linux" | ||
1188 | * End: | ||
1189 | */ | ||
diff --git a/fs/dlm/lowcomms.h b/fs/dlm/lowcomms.h index 2d045e0daae1..a9a9618c0d3f 100644 --- a/fs/dlm/lowcomms.h +++ b/fs/dlm/lowcomms.h | |||
@@ -14,8 +14,6 @@ | |||
14 | #ifndef __LOWCOMMS_DOT_H__ | 14 | #ifndef __LOWCOMMS_DOT_H__ |
15 | #define __LOWCOMMS_DOT_H__ | 15 | #define __LOWCOMMS_DOT_H__ |
16 | 16 | ||
17 | int dlm_lowcomms_init(void); | ||
18 | void dlm_lowcomms_exit(void); | ||
19 | int dlm_lowcomms_start(void); | 17 | int dlm_lowcomms_start(void); |
20 | void dlm_lowcomms_stop(void); | 18 | void dlm_lowcomms_stop(void); |
21 | int dlm_lowcomms_close(int nodeid); | 19 | int dlm_lowcomms_close(int nodeid); |
diff --git a/fs/dlm/main.c b/fs/dlm/main.c index a8da8dc36b2e..162fbae58fe5 100644 --- a/fs/dlm/main.c +++ b/fs/dlm/main.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include "lock.h" | 16 | #include "lock.h" |
17 | #include "user.h" | 17 | #include "user.h" |
18 | #include "memory.h" | 18 | #include "memory.h" |
19 | #include "lowcomms.h" | ||
20 | #include "config.h" | 19 | #include "config.h" |
21 | 20 | ||
22 | #ifdef CONFIG_DLM_DEBUG | 21 | #ifdef CONFIG_DLM_DEBUG |
@@ -47,20 +46,14 @@ static int __init init_dlm(void) | |||
47 | if (error) | 46 | if (error) |
48 | goto out_config; | 47 | goto out_config; |
49 | 48 | ||
50 | error = dlm_lowcomms_init(); | ||
51 | if (error) | ||
52 | goto out_debug; | ||
53 | |||
54 | error = dlm_user_init(); | 49 | error = dlm_user_init(); |
55 | if (error) | 50 | if (error) |
56 | goto out_lowcomms; | 51 | goto out_debug; |
57 | 52 | ||
58 | printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); | 53 | printk("DLM (built %s %s) installed\n", __DATE__, __TIME__); |
59 | 54 | ||
60 | return 0; | 55 | return 0; |
61 | 56 | ||
62 | out_lowcomms: | ||
63 | dlm_lowcomms_exit(); | ||
64 | out_debug: | 57 | out_debug: |
65 | dlm_unregister_debugfs(); | 58 | dlm_unregister_debugfs(); |
66 | out_config: | 59 | out_config: |
@@ -76,7 +69,6 @@ static int __init init_dlm(void) | |||
76 | static void __exit exit_dlm(void) | 69 | static void __exit exit_dlm(void) |
77 | { | 70 | { |
78 | dlm_user_exit(); | 71 | dlm_user_exit(); |
79 | dlm_lowcomms_exit(); | ||
80 | dlm_config_exit(); | 72 | dlm_config_exit(); |
81 | dlm_memory_exit(); | 73 | dlm_memory_exit(); |
82 | dlm_lockspace_exit(); | 74 | dlm_lockspace_exit(); |
diff --git a/fs/dlm/member.c b/fs/dlm/member.c index a3f7de7f3a8f..85e2897bd740 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c | |||
@@ -186,6 +186,14 @@ int dlm_recover_members(struct dlm_ls *ls, struct dlm_recover *rv, int *neg_out) | |||
186 | struct dlm_member *memb, *safe; | 186 | struct dlm_member *memb, *safe; |
187 | int i, error, found, pos = 0, neg = 0, low = -1; | 187 | int i, error, found, pos = 0, neg = 0, low = -1; |
188 | 188 | ||
189 | /* previously removed members that we've not finished removing need to | ||
190 | count as a negative change so the "neg" recovery steps will happen */ | ||
191 | |||
192 | list_for_each_entry(memb, &ls->ls_nodes_gone, list) { | ||
193 | log_debug(ls, "prev removed member %d", memb->nodeid); | ||
194 | neg++; | ||
195 | } | ||
196 | |||
189 | /* move departed members from ls_nodes to ls_nodes_gone */ | 197 | /* move departed members from ls_nodes to ls_nodes_gone */ |
190 | 198 | ||
191 | list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { | 199 | list_for_each_entry_safe(memb, safe, &ls->ls_nodes, list) { |
diff --git a/fs/dlm/memory.c b/fs/dlm/memory.c index 989b608fd836..5352b03ff5aa 100644 --- a/fs/dlm/memory.c +++ b/fs/dlm/memory.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include "config.h" | 15 | #include "config.h" |
16 | #include "memory.h" | 16 | #include "memory.h" |
17 | 17 | ||
18 | static kmem_cache_t *lkb_cache; | 18 | static struct kmem_cache *lkb_cache; |
19 | 19 | ||
20 | 20 | ||
21 | int dlm_memory_init(void) | 21 | int dlm_memory_init(void) |
diff --git a/fs/dlm/rcom.c b/fs/dlm/rcom.c index 518239a8b1e9..4cc31be9cd9d 100644 --- a/fs/dlm/rcom.c +++ b/fs/dlm/rcom.c | |||
@@ -90,13 +90,28 @@ static int check_config(struct dlm_ls *ls, struct rcom_config *rf, int nodeid) | |||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | static void allow_sync_reply(struct dlm_ls *ls, uint64_t *new_seq) | ||
94 | { | ||
95 | spin_lock(&ls->ls_rcom_spin); | ||
96 | *new_seq = ++ls->ls_rcom_seq; | ||
97 | set_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
98 | spin_unlock(&ls->ls_rcom_spin); | ||
99 | } | ||
100 | |||
101 | static void disallow_sync_reply(struct dlm_ls *ls) | ||
102 | { | ||
103 | spin_lock(&ls->ls_rcom_spin); | ||
104 | clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
105 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | ||
106 | spin_unlock(&ls->ls_rcom_spin); | ||
107 | } | ||
108 | |||
93 | int dlm_rcom_status(struct dlm_ls *ls, int nodeid) | 109 | int dlm_rcom_status(struct dlm_ls *ls, int nodeid) |
94 | { | 110 | { |
95 | struct dlm_rcom *rc; | 111 | struct dlm_rcom *rc; |
96 | struct dlm_mhandle *mh; | 112 | struct dlm_mhandle *mh; |
97 | int error = 0; | 113 | int error = 0; |
98 | 114 | ||
99 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
100 | ls->ls_recover_nodeid = nodeid; | 115 | ls->ls_recover_nodeid = nodeid; |
101 | 116 | ||
102 | if (nodeid == dlm_our_nodeid()) { | 117 | if (nodeid == dlm_our_nodeid()) { |
@@ -108,12 +123,14 @@ int dlm_rcom_status(struct dlm_ls *ls, int nodeid) | |||
108 | error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh); | 123 | error = create_rcom(ls, nodeid, DLM_RCOM_STATUS, 0, &rc, &mh); |
109 | if (error) | 124 | if (error) |
110 | goto out; | 125 | goto out; |
111 | rc->rc_id = ++ls->ls_rcom_seq; | 126 | |
127 | allow_sync_reply(ls, &rc->rc_id); | ||
128 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
112 | 129 | ||
113 | send_rcom(ls, mh, rc); | 130 | send_rcom(ls, mh, rc); |
114 | 131 | ||
115 | error = dlm_wait_function(ls, &rcom_response); | 132 | error = dlm_wait_function(ls, &rcom_response); |
116 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | 133 | disallow_sync_reply(ls); |
117 | if (error) | 134 | if (error) |
118 | goto out; | 135 | goto out; |
119 | 136 | ||
@@ -150,14 +167,21 @@ static void receive_rcom_status(struct dlm_ls *ls, struct dlm_rcom *rc_in) | |||
150 | 167 | ||
151 | static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | 168 | static void receive_sync_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) |
152 | { | 169 | { |
153 | if (rc_in->rc_id != ls->ls_rcom_seq) { | 170 | spin_lock(&ls->ls_rcom_spin); |
154 | log_debug(ls, "reject old reply %d got %llx wanted %llx", | 171 | if (!test_bit(LSFL_RCOM_WAIT, &ls->ls_flags) || |
155 | rc_in->rc_type, rc_in->rc_id, ls->ls_rcom_seq); | 172 | rc_in->rc_id != ls->ls_rcom_seq) { |
156 | return; | 173 | log_debug(ls, "reject reply %d from %d seq %llx expect %llx", |
174 | rc_in->rc_type, rc_in->rc_header.h_nodeid, | ||
175 | (unsigned long long)rc_in->rc_id, | ||
176 | (unsigned long long)ls->ls_rcom_seq); | ||
177 | goto out; | ||
157 | } | 178 | } |
158 | memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length); | 179 | memcpy(ls->ls_recover_buf, rc_in, rc_in->rc_header.h_length); |
159 | set_bit(LSFL_RCOM_READY, &ls->ls_flags); | 180 | set_bit(LSFL_RCOM_READY, &ls->ls_flags); |
181 | clear_bit(LSFL_RCOM_WAIT, &ls->ls_flags); | ||
160 | wake_up(&ls->ls_wait_general); | 182 | wake_up(&ls->ls_wait_general); |
183 | out: | ||
184 | spin_unlock(&ls->ls_rcom_spin); | ||
161 | } | 185 | } |
162 | 186 | ||
163 | static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | 187 | static void receive_rcom_status_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) |
@@ -171,7 +195,6 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) | |||
171 | struct dlm_mhandle *mh; | 195 | struct dlm_mhandle *mh; |
172 | int error = 0, len = sizeof(struct dlm_rcom); | 196 | int error = 0, len = sizeof(struct dlm_rcom); |
173 | 197 | ||
174 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
175 | ls->ls_recover_nodeid = nodeid; | 198 | ls->ls_recover_nodeid = nodeid; |
176 | 199 | ||
177 | if (nodeid == dlm_our_nodeid()) { | 200 | if (nodeid == dlm_our_nodeid()) { |
@@ -185,12 +208,14 @@ int dlm_rcom_names(struct dlm_ls *ls, int nodeid, char *last_name, int last_len) | |||
185 | if (error) | 208 | if (error) |
186 | goto out; | 209 | goto out; |
187 | memcpy(rc->rc_buf, last_name, last_len); | 210 | memcpy(rc->rc_buf, last_name, last_len); |
188 | rc->rc_id = ++ls->ls_rcom_seq; | 211 | |
212 | allow_sync_reply(ls, &rc->rc_id); | ||
213 | memset(ls->ls_recover_buf, 0, dlm_config.buffer_size); | ||
189 | 214 | ||
190 | send_rcom(ls, mh, rc); | 215 | send_rcom(ls, mh, rc); |
191 | 216 | ||
192 | error = dlm_wait_function(ls, &rcom_response); | 217 | error = dlm_wait_function(ls, &rcom_response); |
193 | clear_bit(LSFL_RCOM_READY, &ls->ls_flags); | 218 | disallow_sync_reply(ls); |
194 | out: | 219 | out: |
195 | return error; | 220 | return error; |
196 | } | 221 | } |
@@ -370,9 +395,10 @@ static void receive_rcom_lock_reply(struct dlm_ls *ls, struct dlm_rcom *rc_in) | |||
370 | static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) | 395 | static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) |
371 | { | 396 | { |
372 | struct dlm_rcom *rc; | 397 | struct dlm_rcom *rc; |
398 | struct rcom_config *rf; | ||
373 | struct dlm_mhandle *mh; | 399 | struct dlm_mhandle *mh; |
374 | char *mb; | 400 | char *mb; |
375 | int mb_len = sizeof(struct dlm_rcom); | 401 | int mb_len = sizeof(struct dlm_rcom) + sizeof(struct rcom_config); |
376 | 402 | ||
377 | mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); | 403 | mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_KERNEL, &mb); |
378 | if (!mh) | 404 | if (!mh) |
@@ -391,6 +417,9 @@ static int send_ls_not_ready(int nodeid, struct dlm_rcom *rc_in) | |||
391 | rc->rc_id = rc_in->rc_id; | 417 | rc->rc_id = rc_in->rc_id; |
392 | rc->rc_result = -ESRCH; | 418 | rc->rc_result = -ESRCH; |
393 | 419 | ||
420 | rf = (struct rcom_config *) rc->rc_buf; | ||
421 | rf->rf_lvblen = -1; | ||
422 | |||
394 | dlm_rcom_out(rc); | 423 | dlm_rcom_out(rc); |
395 | dlm_lowcomms_commit_buffer(mh); | 424 | dlm_lowcomms_commit_buffer(mh); |
396 | 425 | ||
@@ -412,9 +441,10 @@ void dlm_receive_rcom(struct dlm_header *hd, int nodeid) | |||
412 | 441 | ||
413 | ls = dlm_find_lockspace_global(hd->h_lockspace); | 442 | ls = dlm_find_lockspace_global(hd->h_lockspace); |
414 | if (!ls) { | 443 | if (!ls) { |
415 | log_print("lockspace %x from %d not found", | 444 | log_print("lockspace %x from %d type %x not found", |
416 | hd->h_lockspace, nodeid); | 445 | hd->h_lockspace, nodeid, rc->rc_type); |
417 | send_ls_not_ready(nodeid, rc); | 446 | if (rc->rc_type == DLM_RCOM_STATUS) |
447 | send_ls_not_ready(nodeid, rc); | ||
418 | return; | 448 | return; |
419 | } | 449 | } |
420 | 450 | ||
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c index a5e6d184872e..cf9f6831bab5 100644 --- a/fs/dlm/recover.c +++ b/fs/dlm/recover.c | |||
@@ -252,6 +252,7 @@ static void recover_list_clear(struct dlm_ls *ls) | |||
252 | spin_lock(&ls->ls_recover_list_lock); | 252 | spin_lock(&ls->ls_recover_list_lock); |
253 | list_for_each_entry_safe(r, s, &ls->ls_recover_list, res_recover_list) { | 253 | list_for_each_entry_safe(r, s, &ls->ls_recover_list, res_recover_list) { |
254 | list_del_init(&r->res_recover_list); | 254 | list_del_init(&r->res_recover_list); |
255 | r->res_recover_locks_count = 0; | ||
255 | dlm_put_rsb(r); | 256 | dlm_put_rsb(r); |
256 | ls->ls_recover_list_count--; | 257 | ls->ls_recover_list_count--; |
257 | } | 258 | } |
diff --git a/fs/dlm/recoverd.c b/fs/dlm/recoverd.c index 362e3eff4dc9..650536aa5139 100644 --- a/fs/dlm/recoverd.c +++ b/fs/dlm/recoverd.c | |||
@@ -45,7 +45,7 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
45 | unsigned long start; | 45 | unsigned long start; |
46 | int error, neg = 0; | 46 | int error, neg = 0; |
47 | 47 | ||
48 | log_debug(ls, "recover %llx", rv->seq); | 48 | log_debug(ls, "recover %llx", (unsigned long long)rv->seq); |
49 | 49 | ||
50 | mutex_lock(&ls->ls_recoverd_active); | 50 | mutex_lock(&ls->ls_recoverd_active); |
51 | 51 | ||
@@ -94,14 +94,6 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
94 | } | 94 | } |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * Purge directory-related requests that are saved in requestqueue. | ||
98 | * All dir requests from before recovery are invalid now due to the dir | ||
99 | * rebuild and will be resent by the requesting nodes. | ||
100 | */ | ||
101 | |||
102 | dlm_purge_requestqueue(ls); | ||
103 | |||
104 | /* | ||
105 | * Wait for all nodes to complete directory rebuild. | 97 | * Wait for all nodes to complete directory rebuild. |
106 | */ | 98 | */ |
107 | 99 | ||
@@ -164,10 +156,31 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
164 | */ | 156 | */ |
165 | 157 | ||
166 | dlm_recover_rsbs(ls); | 158 | dlm_recover_rsbs(ls); |
159 | } else { | ||
160 | /* | ||
161 | * Other lockspace members may be going through the "neg" steps | ||
162 | * while also adding us to the lockspace, in which case they'll | ||
163 | * be doing the recover_locks (RS_LOCKS) barrier. | ||
164 | */ | ||
165 | dlm_set_recover_status(ls, DLM_RS_LOCKS); | ||
166 | |||
167 | error = dlm_recover_locks_wait(ls); | ||
168 | if (error) { | ||
169 | log_error(ls, "recover_locks_wait failed %d", error); | ||
170 | goto fail; | ||
171 | } | ||
167 | } | 172 | } |
168 | 173 | ||
169 | dlm_release_root_list(ls); | 174 | dlm_release_root_list(ls); |
170 | 175 | ||
176 | /* | ||
177 | * Purge directory-related requests that are saved in requestqueue. | ||
178 | * All dir requests from before recovery are invalid now due to the dir | ||
179 | * rebuild and will be resent by the requesting nodes. | ||
180 | */ | ||
181 | |||
182 | dlm_purge_requestqueue(ls); | ||
183 | |||
171 | dlm_set_recover_status(ls, DLM_RS_DONE); | 184 | dlm_set_recover_status(ls, DLM_RS_DONE); |
172 | error = dlm_recover_done_wait(ls); | 185 | error = dlm_recover_done_wait(ls); |
173 | if (error) { | 186 | if (error) { |
@@ -199,7 +212,8 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
199 | 212 | ||
200 | dlm_astd_wake(); | 213 | dlm_astd_wake(); |
201 | 214 | ||
202 | log_debug(ls, "recover %llx done: %u ms", rv->seq, | 215 | log_debug(ls, "recover %llx done: %u ms", |
216 | (unsigned long long)rv->seq, | ||
203 | jiffies_to_msecs(jiffies - start)); | 217 | jiffies_to_msecs(jiffies - start)); |
204 | mutex_unlock(&ls->ls_recoverd_active); | 218 | mutex_unlock(&ls->ls_recoverd_active); |
205 | 219 | ||
@@ -207,11 +221,16 @@ static int ls_recover(struct dlm_ls *ls, struct dlm_recover *rv) | |||
207 | 221 | ||
208 | fail: | 222 | fail: |
209 | dlm_release_root_list(ls); | 223 | dlm_release_root_list(ls); |
210 | log_debug(ls, "recover %llx error %d", rv->seq, error); | 224 | log_debug(ls, "recover %llx error %d", |
225 | (unsigned long long)rv->seq, error); | ||
211 | mutex_unlock(&ls->ls_recoverd_active); | 226 | mutex_unlock(&ls->ls_recoverd_active); |
212 | return error; | 227 | return error; |
213 | } | 228 | } |
214 | 229 | ||
230 | /* The dlm_ls_start() that created the rv we take here may already have been | ||
231 | stopped via dlm_ls_stop(); in that case we need to leave the RECOVERY_STOP | ||
232 | flag set. */ | ||
233 | |||
215 | static void do_ls_recovery(struct dlm_ls *ls) | 234 | static void do_ls_recovery(struct dlm_ls *ls) |
216 | { | 235 | { |
217 | struct dlm_recover *rv = NULL; | 236 | struct dlm_recover *rv = NULL; |
@@ -219,7 +238,8 @@ static void do_ls_recovery(struct dlm_ls *ls) | |||
219 | spin_lock(&ls->ls_recover_lock); | 238 | spin_lock(&ls->ls_recover_lock); |
220 | rv = ls->ls_recover_args; | 239 | rv = ls->ls_recover_args; |
221 | ls->ls_recover_args = NULL; | 240 | ls->ls_recover_args = NULL; |
222 | clear_bit(LSFL_RECOVERY_STOP, &ls->ls_flags); | 241 | if (rv && ls->ls_recover_seq == rv->seq) |
242 | clear_bit(LSFL_RECOVERY_STOP, &ls->ls_flags); | ||
223 | spin_unlock(&ls->ls_recover_lock); | 243 | spin_unlock(&ls->ls_recover_lock); |
224 | 244 | ||
225 | if (rv) { | 245 | if (rv) { |
diff --git a/fs/dlm/requestqueue.c b/fs/dlm/requestqueue.c index 7b2b089634a2..65008d79c96d 100644 --- a/fs/dlm/requestqueue.c +++ b/fs/dlm/requestqueue.c | |||
@@ -30,26 +30,36 @@ struct rq_entry { | |||
30 | * lockspace is enabled on some while still suspended on others. | 30 | * lockspace is enabled on some while still suspended on others. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) | 33 | int dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd) |
34 | { | 34 | { |
35 | struct rq_entry *e; | 35 | struct rq_entry *e; |
36 | int length = hd->h_length; | 36 | int length = hd->h_length; |
37 | 37 | int rv = 0; | |
38 | if (dlm_is_removed(ls, nodeid)) | ||
39 | return; | ||
40 | 38 | ||
41 | e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); | 39 | e = kmalloc(sizeof(struct rq_entry) + length, GFP_KERNEL); |
42 | if (!e) { | 40 | if (!e) { |
43 | log_print("dlm_add_requestqueue: out of memory\n"); | 41 | log_print("dlm_add_requestqueue: out of memory\n"); |
44 | return; | 42 | return 0; |
45 | } | 43 | } |
46 | 44 | ||
47 | e->nodeid = nodeid; | 45 | e->nodeid = nodeid; |
48 | memcpy(e->request, hd, length); | 46 | memcpy(e->request, hd, length); |
49 | 47 | ||
48 | /* We need to check dlm_locking_stopped() after taking the mutex to | ||
49 | avoid a race where dlm_recoverd enables locking and runs | ||
50 | process_requestqueue between our earlier dlm_locking_stopped check | ||
51 | and this addition to the requestqueue. */ | ||
52 | |||
50 | mutex_lock(&ls->ls_requestqueue_mutex); | 53 | mutex_lock(&ls->ls_requestqueue_mutex); |
51 | list_add_tail(&e->list, &ls->ls_requestqueue); | 54 | if (dlm_locking_stopped(ls)) |
55 | list_add_tail(&e->list, &ls->ls_requestqueue); | ||
56 | else { | ||
57 | log_debug(ls, "dlm_add_requestqueue skip from %d", nodeid); | ||
58 | kfree(e); | ||
59 | rv = -EAGAIN; | ||
60 | } | ||
52 | mutex_unlock(&ls->ls_requestqueue_mutex); | 61 | mutex_unlock(&ls->ls_requestqueue_mutex); |
62 | return rv; | ||
53 | } | 63 | } |
54 | 64 | ||
55 | int dlm_process_requestqueue(struct dlm_ls *ls) | 65 | int dlm_process_requestqueue(struct dlm_ls *ls) |
@@ -120,6 +130,10 @@ static int purge_request(struct dlm_ls *ls, struct dlm_message *ms, int nodeid) | |||
120 | { | 130 | { |
121 | uint32_t type = ms->m_type; | 131 | uint32_t type = ms->m_type; |
122 | 132 | ||
133 | /* the ls is being cleaned up and freed by release_lockspace */ | ||
134 | if (!ls->ls_count) | ||
135 | return 1; | ||
136 | |||
123 | if (dlm_is_removed(ls, nodeid)) | 137 | if (dlm_is_removed(ls, nodeid)) |
124 | return 1; | 138 | return 1; |
125 | 139 | ||
diff --git a/fs/dlm/requestqueue.h b/fs/dlm/requestqueue.h index 349f0d292d95..6a53ea03335d 100644 --- a/fs/dlm/requestqueue.h +++ b/fs/dlm/requestqueue.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #ifndef __REQUESTQUEUE_DOT_H__ | 13 | #ifndef __REQUESTQUEUE_DOT_H__ |
14 | #define __REQUESTQUEUE_DOT_H__ | 14 | #define __REQUESTQUEUE_DOT_H__ |
15 | 15 | ||
16 | void dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); | 16 | int dlm_add_requestqueue(struct dlm_ls *ls, int nodeid, struct dlm_header *hd); |
17 | int dlm_process_requestqueue(struct dlm_ls *ls); | 17 | int dlm_process_requestqueue(struct dlm_ls *ls); |
18 | void dlm_wait_requestqueue(struct dlm_ls *ls); | 18 | void dlm_wait_requestqueue(struct dlm_ls *ls); |
19 | void dlm_purge_requestqueue(struct dlm_ls *ls); | 19 | void dlm_purge_requestqueue(struct dlm_ls *ls); |
diff --git a/fs/dnotify.c b/fs/dnotify.c index 2b0442db67e0..1f26a2b9eee1 100644 --- a/fs/dnotify.c +++ b/fs/dnotify.c | |||
@@ -23,7 +23,7 @@ | |||
23 | 23 | ||
24 | int dir_notify_enable __read_mostly = 1; | 24 | int dir_notify_enable __read_mostly = 1; |
25 | 25 | ||
26 | static kmem_cache_t *dn_cache __read_mostly; | 26 | static struct kmem_cache *dn_cache __read_mostly; |
27 | 27 | ||
28 | static void redo_inode_mask(struct inode *inode) | 28 | static void redo_inode_mask(struct inode *inode) |
29 | { | 29 | { |
@@ -77,7 +77,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) | |||
77 | inode = filp->f_dentry->d_inode; | 77 | inode = filp->f_dentry->d_inode; |
78 | if (!S_ISDIR(inode->i_mode)) | 78 | if (!S_ISDIR(inode->i_mode)) |
79 | return -ENOTDIR; | 79 | return -ENOTDIR; |
80 | dn = kmem_cache_alloc(dn_cache, SLAB_KERNEL); | 80 | dn = kmem_cache_alloc(dn_cache, GFP_KERNEL); |
81 | if (dn == NULL) | 81 | if (dn == NULL) |
82 | return -ENOMEM; | 82 | return -ENOMEM; |
83 | spin_lock(&inode->i_lock); | 83 | spin_lock(&inode->i_lock); |
diff --git a/fs/dquot.c b/fs/dquot.c index 9af789567e51..f9cd5e23ebdf 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -131,7 +131,7 @@ static struct quota_format_type *quota_formats; /* List of registered formats */ | |||
131 | static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES; | 131 | static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES; |
132 | 132 | ||
133 | /* SLAB cache for dquot structures */ | 133 | /* SLAB cache for dquot structures */ |
134 | static kmem_cache_t *dquot_cachep; | 134 | static struct kmem_cache *dquot_cachep; |
135 | 135 | ||
136 | int register_quota_format(struct quota_format_type *fmt) | 136 | int register_quota_format(struct quota_format_type *fmt) |
137 | { | 137 | { |
@@ -600,7 +600,7 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
600 | { | 600 | { |
601 | struct dquot *dquot; | 601 | struct dquot *dquot; |
602 | 602 | ||
603 | dquot = kmem_cache_alloc(dquot_cachep, SLAB_NOFS); | 603 | dquot = kmem_cache_alloc(dquot_cachep, GFP_NOFS); |
604 | if(!dquot) | 604 | if(!dquot) |
605 | return NODQUOT; | 605 | return NODQUOT; |
606 | 606 | ||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 136175a69332..7196f50fe152 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -628,7 +628,7 @@ int ecryptfs_decrypt_page(struct file *file, struct page *page) | |||
628 | num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; | 628 | num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; |
629 | base_extent = (page->index * num_extents_per_page); | 629 | base_extent = (page->index * num_extents_per_page); |
630 | lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache, | 630 | lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache, |
631 | SLAB_KERNEL); | 631 | GFP_KERNEL); |
632 | if (!lower_page_virt) { | 632 | if (!lower_page_virt) { |
633 | rc = -ENOMEM; | 633 | rc = -ENOMEM; |
634 | ecryptfs_printk(KERN_ERR, "Error getting page for encrypted " | 634 | ecryptfs_printk(KERN_ERR, "Error getting page for encrypted " |
@@ -820,7 +820,8 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat) | |||
820 | crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0, | 820 | crypt_stat->tfm = crypto_alloc_blkcipher(full_alg_name, 0, |
821 | CRYPTO_ALG_ASYNC); | 821 | CRYPTO_ALG_ASYNC); |
822 | kfree(full_alg_name); | 822 | kfree(full_alg_name); |
823 | if (!crypt_stat->tfm) { | 823 | if (IS_ERR(crypt_stat->tfm)) { |
824 | rc = PTR_ERR(crypt_stat->tfm); | ||
824 | ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " | 825 | ecryptfs_printk(KERN_ERR, "cryptfs: init_crypt_ctx(): " |
825 | "Error initializing cipher [%s]\n", | 826 | "Error initializing cipher [%s]\n", |
826 | crypt_stat->cipher); | 827 | crypt_stat->cipher); |
@@ -1333,7 +1334,7 @@ int ecryptfs_write_headers(struct dentry *ecryptfs_dentry, | |||
1333 | goto out; | 1334 | goto out; |
1334 | } | 1335 | } |
1335 | /* Released in this function */ | 1336 | /* Released in this function */ |
1336 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, SLAB_USER); | 1337 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_0, GFP_USER); |
1337 | if (!page_virt) { | 1338 | if (!page_virt) { |
1338 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | 1339 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); |
1339 | rc = -ENOMEM; | 1340 | rc = -ENOMEM; |
@@ -1492,7 +1493,7 @@ int ecryptfs_read_headers(struct dentry *ecryptfs_dentry, | |||
1492 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1493 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; |
1493 | 1494 | ||
1494 | /* Read the first page from the underlying file */ | 1495 | /* Read the first page from the underlying file */ |
1495 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, SLAB_USER); | 1496 | page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); |
1496 | if (!page_virt) { | 1497 | if (!page_virt) { |
1497 | rc = -ENOMEM; | 1498 | rc = -ENOMEM; |
1498 | ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n"); | 1499 | ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n"); |
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 0b9992ab990f..52d1e36dc746 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c | |||
@@ -57,6 +57,12 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
57 | rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); | 57 | rc = lower_dentry->d_op->d_revalidate(lower_dentry, nd); |
58 | nd->dentry = dentry_save; | 58 | nd->dentry = dentry_save; |
59 | nd->mnt = vfsmount_save; | 59 | nd->mnt = vfsmount_save; |
60 | if (dentry->d_inode) { | ||
61 | struct inode *lower_inode = | ||
62 | ecryptfs_inode_to_lower(dentry->d_inode); | ||
63 | |||
64 | ecryptfs_copy_attr_all(dentry->d_inode, lower_inode); | ||
65 | } | ||
60 | out: | 66 | out: |
61 | return rc; | 67 | return rc; |
62 | } | 68 | } |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index a92ef05eff8f..42099e779a56 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -250,7 +250,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
250 | int lower_flags; | 250 | int lower_flags; |
251 | 251 | ||
252 | /* Released in ecryptfs_release or end of function if failure */ | 252 | /* Released in ecryptfs_release or end of function if failure */ |
253 | file_info = kmem_cache_alloc(ecryptfs_file_info_cache, SLAB_KERNEL); | 253 | file_info = kmem_cache_alloc(ecryptfs_file_info_cache, GFP_KERNEL); |
254 | ecryptfs_set_file_private(file, file_info); | 254 | ecryptfs_set_file_private(file, file_info); |
255 | if (!file_info) { | 255 | if (!file_info) { |
256 | ecryptfs_printk(KERN_ERR, | 256 | ecryptfs_printk(KERN_ERR, |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index ff4865d24f0f..8a1945a84c36 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -369,7 +369,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
369 | BUG_ON(!atomic_read(&lower_dentry->d_count)); | 369 | BUG_ON(!atomic_read(&lower_dentry->d_count)); |
370 | ecryptfs_set_dentry_private(dentry, | 370 | ecryptfs_set_dentry_private(dentry, |
371 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | 371 | kmem_cache_alloc(ecryptfs_dentry_info_cache, |
372 | SLAB_KERNEL)); | 372 | GFP_KERNEL)); |
373 | if (!ecryptfs_dentry_to_private(dentry)) { | 373 | if (!ecryptfs_dentry_to_private(dentry)) { |
374 | rc = -ENOMEM; | 374 | rc = -ENOMEM; |
375 | ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting " | 375 | ecryptfs_printk(KERN_ERR, "Out of memory whilst attempting " |
@@ -404,7 +404,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
404 | /* Released in this function */ | 404 | /* Released in this function */ |
405 | page_virt = | 405 | page_virt = |
406 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, | 406 | (char *)kmem_cache_alloc(ecryptfs_header_cache_2, |
407 | SLAB_USER); | 407 | GFP_USER); |
408 | if (!page_virt) { | 408 | if (!page_virt) { |
409 | rc = -ENOMEM; | 409 | rc = -ENOMEM; |
410 | ecryptfs_printk(KERN_ERR, | 410 | ecryptfs_printk(KERN_ERR, |
@@ -470,6 +470,7 @@ out_lock: | |||
470 | unlock_dir(lower_dir_dentry); | 470 | unlock_dir(lower_dir_dentry); |
471 | dput(lower_new_dentry); | 471 | dput(lower_new_dentry); |
472 | dput(lower_old_dentry); | 472 | dput(lower_old_dentry); |
473 | d_drop(lower_old_dentry); | ||
473 | d_drop(new_dentry); | 474 | d_drop(new_dentry); |
474 | d_drop(old_dentry); | 475 | d_drop(old_dentry); |
475 | return rc; | 476 | return rc; |
@@ -484,7 +485,7 @@ static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) | |||
484 | lock_parent(lower_dentry); | 485 | lock_parent(lower_dentry); |
485 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | 486 | rc = vfs_unlink(lower_dir_inode, lower_dentry); |
486 | if (rc) { | 487 | if (rc) { |
487 | ecryptfs_printk(KERN_ERR, "Error in vfs_unlink\n"); | 488 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); |
488 | goto out_unlock; | 489 | goto out_unlock; |
489 | } | 490 | } |
490 | ecryptfs_copy_attr_times(dir, lower_dir_inode); | 491 | ecryptfs_copy_attr_times(dir, lower_dir_inode); |
@@ -630,6 +631,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
630 | ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); | 631 | ecryptfs_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); |
631 | out_lock: | 632 | out_lock: |
632 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | 633 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
634 | dput(lower_new_dentry->d_parent); | ||
635 | dput(lower_old_dentry->d_parent); | ||
633 | dput(lower_new_dentry); | 636 | dput(lower_new_dentry); |
634 | dput(lower_old_dentry); | 637 | dput(lower_old_dentry); |
635 | return rc; | 638 | return rc; |
@@ -792,7 +795,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
792 | /* Released at out_free: label */ | 795 | /* Released at out_free: label */ |
793 | ecryptfs_set_file_private(&fake_ecryptfs_file, | 796 | ecryptfs_set_file_private(&fake_ecryptfs_file, |
794 | kmem_cache_alloc(ecryptfs_file_info_cache, | 797 | kmem_cache_alloc(ecryptfs_file_info_cache, |
795 | SLAB_KERNEL)); | 798 | GFP_KERNEL)); |
796 | if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { | 799 | if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { |
797 | rc = -ENOMEM; | 800 | rc = -ENOMEM; |
798 | goto out; | 801 | goto out; |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index c3746f56d162..745c0f1bfbbd 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -207,7 +207,7 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
207 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or | 207 | /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or |
208 | * at end of function upon failure */ | 208 | * at end of function upon failure */ |
209 | auth_tok_list_item = | 209 | auth_tok_list_item = |
210 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, SLAB_KERNEL); | 210 | kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); |
211 | if (!auth_tok_list_item) { | 211 | if (!auth_tok_list_item) { |
212 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); | 212 | ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); |
213 | rc = -ENOMEM; | 213 | rc = -ENOMEM; |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index a78d87d14baf..3ede12b25933 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -378,7 +378,7 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
378 | /* Released in ecryptfs_put_super() */ | 378 | /* Released in ecryptfs_put_super() */ |
379 | ecryptfs_set_superblock_private(sb, | 379 | ecryptfs_set_superblock_private(sb, |
380 | kmem_cache_alloc(ecryptfs_sb_info_cache, | 380 | kmem_cache_alloc(ecryptfs_sb_info_cache, |
381 | SLAB_KERNEL)); | 381 | GFP_KERNEL)); |
382 | if (!ecryptfs_superblock_to_private(sb)) { | 382 | if (!ecryptfs_superblock_to_private(sb)) { |
383 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | 383 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); |
384 | rc = -ENOMEM; | 384 | rc = -ENOMEM; |
@@ -402,7 +402,7 @@ ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
402 | /* through deactivate_super(sb) from get_sb_nodev() */ | 402 | /* through deactivate_super(sb) from get_sb_nodev() */ |
403 | ecryptfs_set_dentry_private(sb->s_root, | 403 | ecryptfs_set_dentry_private(sb->s_root, |
404 | kmem_cache_alloc(ecryptfs_dentry_info_cache, | 404 | kmem_cache_alloc(ecryptfs_dentry_info_cache, |
405 | SLAB_KERNEL)); | 405 | GFP_KERNEL)); |
406 | if (!ecryptfs_dentry_to_private(sb->s_root)) { | 406 | if (!ecryptfs_dentry_to_private(sb->s_root)) { |
407 | ecryptfs_printk(KERN_ERR, | 407 | ecryptfs_printk(KERN_ERR, |
408 | "dentry_info_cache alloc failed\n"); | 408 | "dentry_info_cache alloc failed\n"); |
@@ -546,7 +546,7 @@ inode_info_init_once(void *vptr, struct kmem_cache *cachep, unsigned long flags) | |||
546 | } | 546 | } |
547 | 547 | ||
548 | static struct ecryptfs_cache_info { | 548 | static struct ecryptfs_cache_info { |
549 | kmem_cache_t **cache; | 549 | struct kmem_cache **cache; |
550 | const char *name; | 550 | const char *name; |
551 | size_t size; | 551 | size_t size; |
552 | void (*ctor)(void*, struct kmem_cache *, unsigned long); | 552 | void (*ctor)(void*, struct kmem_cache *, unsigned long); |
@@ -691,7 +691,7 @@ static ssize_t version_show(struct ecryptfs_obj *obj, char *buff) | |||
691 | 691 | ||
692 | static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version); | 692 | static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version); |
693 | 693 | ||
694 | struct ecryptfs_version_str_map_elem { | 694 | static struct ecryptfs_version_str_map_elem { |
695 | u32 flag; | 695 | u32 flag; |
696 | char *str; | 696 | char *str; |
697 | } ecryptfs_version_str_map[] = { | 697 | } ecryptfs_version_str_map[] = { |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 825757ae4867..eaa5daaf106e 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -50,7 +50,7 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb) | |||
50 | struct inode *inode = NULL; | 50 | struct inode *inode = NULL; |
51 | 51 | ||
52 | ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache, | 52 | ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache, |
53 | SLAB_KERNEL); | 53 | GFP_KERNEL); |
54 | if (unlikely(!ecryptfs_inode)) | 54 | if (unlikely(!ecryptfs_inode)) |
55 | goto out; | 55 | goto out; |
56 | ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat); | 56 | ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat); |
diff --git a/fs/efs/super.c b/fs/efs/super.c index b3f50651eb6b..dfebf21289f4 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c | |||
@@ -52,12 +52,12 @@ static struct pt_types sgi_pt_types[] = { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | 54 | ||
55 | static kmem_cache_t * efs_inode_cachep; | 55 | static struct kmem_cache * efs_inode_cachep; |
56 | 56 | ||
57 | static struct inode *efs_alloc_inode(struct super_block *sb) | 57 | static struct inode *efs_alloc_inode(struct super_block *sb) |
58 | { | 58 | { |
59 | struct efs_inode_info *ei; | 59 | struct efs_inode_info *ei; |
60 | ei = (struct efs_inode_info *)kmem_cache_alloc(efs_inode_cachep, SLAB_KERNEL); | 60 | ei = (struct efs_inode_info *)kmem_cache_alloc(efs_inode_cachep, GFP_KERNEL); |
61 | if (!ei) | 61 | if (!ei) |
62 | return NULL; | 62 | return NULL; |
63 | return &ei->vfs_inode; | 63 | return &ei->vfs_inode; |
@@ -68,7 +68,7 @@ static void efs_destroy_inode(struct inode *inode) | |||
68 | kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); | 68 | kmem_cache_free(efs_inode_cachep, INODE_INFO(inode)); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 71 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
72 | { | 72 | { |
73 | struct efs_inode_info *ei = (struct efs_inode_info *) foo; | 73 | struct efs_inode_info *ei = (struct efs_inode_info *) foo; |
74 | 74 | ||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index ae228ec54e94..88a6f8d0b88e 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -283,10 +283,10 @@ static struct mutex epmutex; | |||
283 | static struct poll_safewake psw; | 283 | static struct poll_safewake psw; |
284 | 284 | ||
285 | /* Slab cache used to allocate "struct epitem" */ | 285 | /* Slab cache used to allocate "struct epitem" */ |
286 | static kmem_cache_t *epi_cache __read_mostly; | 286 | static struct kmem_cache *epi_cache __read_mostly; |
287 | 287 | ||
288 | /* Slab cache used to allocate "struct eppoll_entry" */ | 288 | /* Slab cache used to allocate "struct eppoll_entry" */ |
289 | static kmem_cache_t *pwq_cache __read_mostly; | 289 | static struct kmem_cache *pwq_cache __read_mostly; |
290 | 290 | ||
291 | /* Virtual fs used to allocate inodes for eventpoll files */ | 291 | /* Virtual fs used to allocate inodes for eventpoll files */ |
292 | static struct vfsmount *eventpoll_mnt __read_mostly; | 292 | static struct vfsmount *eventpoll_mnt __read_mostly; |
@@ -961,7 +961,7 @@ static void ep_ptable_queue_proc(struct file *file, wait_queue_head_t *whead, | |||
961 | struct epitem *epi = ep_item_from_epqueue(pt); | 961 | struct epitem *epi = ep_item_from_epqueue(pt); |
962 | struct eppoll_entry *pwq; | 962 | struct eppoll_entry *pwq; |
963 | 963 | ||
964 | if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, SLAB_KERNEL))) { | 964 | if (epi->nwait >= 0 && (pwq = kmem_cache_alloc(pwq_cache, GFP_KERNEL))) { |
965 | init_waitqueue_func_entry(&pwq->wait, ep_poll_callback); | 965 | init_waitqueue_func_entry(&pwq->wait, ep_poll_callback); |
966 | pwq->whead = whead; | 966 | pwq->whead = whead; |
967 | pwq->base = epi; | 967 | pwq->base = epi; |
@@ -1004,7 +1004,7 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
1004 | struct ep_pqueue epq; | 1004 | struct ep_pqueue epq; |
1005 | 1005 | ||
1006 | error = -ENOMEM; | 1006 | error = -ENOMEM; |
1007 | if (!(epi = kmem_cache_alloc(epi_cache, SLAB_KERNEL))) | 1007 | if (!(epi = kmem_cache_alloc(epi_cache, GFP_KERNEL))) |
1008 | goto eexit_1; | 1008 | goto eexit_1; |
1009 | 1009 | ||
1010 | /* Item initialization follow here ... */ | 1010 | /* Item initialization follow here ... */ |
@@ -404,7 +404,7 @@ int setup_arg_pages(struct linux_binprm *bprm, | |||
404 | bprm->loader += stack_base; | 404 | bprm->loader += stack_base; |
405 | bprm->exec += stack_base; | 405 | bprm->exec += stack_base; |
406 | 406 | ||
407 | mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); | 407 | mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL); |
408 | if (!mpnt) | 408 | if (!mpnt) |
409 | return -ENOMEM; | 409 | return -ENOMEM; |
410 | 410 | ||
@@ -1515,7 +1515,8 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1515 | ispipe = 1; | 1515 | ispipe = 1; |
1516 | } else | 1516 | } else |
1517 | file = filp_open(corename, | 1517 | file = filp_open(corename, |
1518 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE, 0600); | 1518 | O_CREAT | 2 | O_NOFOLLOW | O_LARGEFILE | flag, |
1519 | 0600); | ||
1519 | if (IS_ERR(file)) | 1520 | if (IS_ERR(file)) |
1520 | goto fail_unlock; | 1521 | goto fail_unlock; |
1521 | inode = file->f_dentry->d_inode; | 1522 | inode = file->f_dentry->d_inode; |
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 1dfba77eab10..e3cf8c81507f 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
@@ -44,6 +44,7 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
44 | if (!S_ISDIR(inode->i_mode)) | 44 | if (!S_ISDIR(inode->i_mode)) |
45 | flags &= ~EXT2_DIRSYNC_FL; | 45 | flags &= ~EXT2_DIRSYNC_FL; |
46 | 46 | ||
47 | mutex_lock(&inode->i_mutex); | ||
47 | oldflags = ei->i_flags; | 48 | oldflags = ei->i_flags; |
48 | 49 | ||
49 | /* | 50 | /* |
@@ -53,13 +54,16 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
53 | * This test looks nicer. Thanks to Pauline Middelink | 54 | * This test looks nicer. Thanks to Pauline Middelink |
54 | */ | 55 | */ |
55 | if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { | 56 | if ((flags ^ oldflags) & (EXT2_APPEND_FL | EXT2_IMMUTABLE_FL)) { |
56 | if (!capable(CAP_LINUX_IMMUTABLE)) | 57 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
58 | mutex_unlock(&inode->i_mutex); | ||
57 | return -EPERM; | 59 | return -EPERM; |
60 | } | ||
58 | } | 61 | } |
59 | 62 | ||
60 | flags = flags & EXT2_FL_USER_MODIFIABLE; | 63 | flags = flags & EXT2_FL_USER_MODIFIABLE; |
61 | flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; | 64 | flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; |
62 | ei->i_flags = flags; | 65 | ei->i_flags = flags; |
66 | mutex_unlock(&inode->i_mutex); | ||
63 | 67 | ||
64 | ext2_set_inode_flags(inode); | 68 | ext2_set_inode_flags(inode); |
65 | inode->i_ctime = CURRENT_TIME_SEC; | 69 | inode->i_ctime = CURRENT_TIME_SEC; |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index d8b9abd95d07..255cef5f7420 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -135,12 +135,12 @@ static void ext2_put_super (struct super_block * sb) | |||
135 | return; | 135 | return; |
136 | } | 136 | } |
137 | 137 | ||
138 | static kmem_cache_t * ext2_inode_cachep; | 138 | static struct kmem_cache * ext2_inode_cachep; |
139 | 139 | ||
140 | static struct inode *ext2_alloc_inode(struct super_block *sb) | 140 | static struct inode *ext2_alloc_inode(struct super_block *sb) |
141 | { | 141 | { |
142 | struct ext2_inode_info *ei; | 142 | struct ext2_inode_info *ei; |
143 | ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, SLAB_KERNEL); | 143 | ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL); |
144 | if (!ei) | 144 | if (!ei) |
145 | return NULL; | 145 | return NULL; |
146 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 146 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
@@ -156,7 +156,7 @@ static void ext2_destroy_inode(struct inode *inode) | |||
156 | kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); | 156 | kmem_cache_free(ext2_inode_cachep, EXT2_I(inode)); |
157 | } | 157 | } |
158 | 158 | ||
159 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 159 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
160 | { | 160 | { |
161 | struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; | 161 | struct ext2_inode_info *ei = (struct ext2_inode_info *) foo; |
162 | 162 | ||
@@ -1090,8 +1090,10 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1090 | { | 1090 | { |
1091 | struct super_block *sb = dentry->d_sb; | 1091 | struct super_block *sb = dentry->d_sb; |
1092 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 1092 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
1093 | struct ext2_super_block *es = sbi->s_es; | ||
1093 | unsigned long overhead; | 1094 | unsigned long overhead; |
1094 | int i; | 1095 | int i; |
1096 | u64 fsid; | ||
1095 | 1097 | ||
1096 | if (test_opt (sb, MINIX_DF)) | 1098 | if (test_opt (sb, MINIX_DF)) |
1097 | overhead = 0; | 1099 | overhead = 0; |
@@ -1104,7 +1106,7 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1104 | * All of the blocks before first_data_block are | 1106 | * All of the blocks before first_data_block are |
1105 | * overhead | 1107 | * overhead |
1106 | */ | 1108 | */ |
1107 | overhead = le32_to_cpu(sbi->s_es->s_first_data_block); | 1109 | overhead = le32_to_cpu(es->s_first_data_block); |
1108 | 1110 | ||
1109 | /* | 1111 | /* |
1110 | * Add the overhead attributed to the superblock and | 1112 | * Add the overhead attributed to the superblock and |
@@ -1125,14 +1127,18 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1125 | 1127 | ||
1126 | buf->f_type = EXT2_SUPER_MAGIC; | 1128 | buf->f_type = EXT2_SUPER_MAGIC; |
1127 | buf->f_bsize = sb->s_blocksize; | 1129 | buf->f_bsize = sb->s_blocksize; |
1128 | buf->f_blocks = le32_to_cpu(sbi->s_es->s_blocks_count) - overhead; | 1130 | buf->f_blocks = le32_to_cpu(es->s_blocks_count) - overhead; |
1129 | buf->f_bfree = ext2_count_free_blocks(sb); | 1131 | buf->f_bfree = ext2_count_free_blocks(sb); |
1130 | buf->f_bavail = buf->f_bfree - le32_to_cpu(sbi->s_es->s_r_blocks_count); | 1132 | buf->f_bavail = buf->f_bfree - le32_to_cpu(es->s_r_blocks_count); |
1131 | if (buf->f_bfree < le32_to_cpu(sbi->s_es->s_r_blocks_count)) | 1133 | if (buf->f_bfree < le32_to_cpu(es->s_r_blocks_count)) |
1132 | buf->f_bavail = 0; | 1134 | buf->f_bavail = 0; |
1133 | buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count); | 1135 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
1134 | buf->f_ffree = ext2_count_free_inodes (sb); | 1136 | buf->f_ffree = ext2_count_free_inodes(sb); |
1135 | buf->f_namelen = EXT2_NAME_LEN; | 1137 | buf->f_namelen = EXT2_NAME_LEN; |
1138 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | ||
1139 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | ||
1140 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; | ||
1141 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; | ||
1136 | return 0; | 1142 | return 0; |
1137 | } | 1143 | } |
1138 | 1144 | ||
diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index af52a7f8b291..247efd0b51d6 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c | |||
@@ -342,12 +342,9 @@ static void ext2_xattr_update_super_block(struct super_block *sb) | |||
342 | if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR)) | 342 | if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR)) |
343 | return; | 343 | return; |
344 | 344 | ||
345 | lock_super(sb); | 345 | EXT2_SET_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR); |
346 | EXT2_SB(sb)->s_es->s_feature_compat |= | ||
347 | cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR); | ||
348 | sb->s_dirt = 1; | 346 | sb->s_dirt = 1; |
349 | mark_buffer_dirty(EXT2_SB(sb)->s_sbh); | 347 | mark_buffer_dirty(EXT2_SB(sb)->s_sbh); |
350 | unlock_super(sb); | ||
351 | } | 348 | } |
352 | 349 | ||
353 | /* | 350 | /* |
diff --git a/fs/ext3/Makefile b/fs/ext3/Makefile index 704cd44a40c2..e77766a8b3f0 100644 --- a/fs/ext3/Makefile +++ b/fs/ext3/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | obj-$(CONFIG_EXT3_FS) += ext3.o | 5 | obj-$(CONFIG_EXT3_FS) += ext3.o |
6 | 6 | ||
7 | ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ | 7 | ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ |
8 | ioctl.o namei.o super.o symlink.o hash.o resize.o | 8 | ioctl.o namei.o super.o symlink.o hash.o resize.o ext3_jbd.o |
9 | 9 | ||
10 | ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o | 10 | ext3-$(CONFIG_EXT3_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o |
11 | ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o | 11 | ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index b41a7d7e20f0..22161740ba29 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -144,7 +144,7 @@ restart: | |||
144 | 144 | ||
145 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); | 145 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); |
146 | while (n) { | 146 | while (n) { |
147 | rsv = list_entry(n, struct ext3_reserve_window_node, rsv_node); | 147 | rsv = rb_entry(n, struct ext3_reserve_window_node, rsv_node); |
148 | if (verbose) | 148 | if (verbose) |
149 | printk("reservation window 0x%p " | 149 | printk("reservation window 0x%p " |
150 | "start: %lu, end: %lu\n", | 150 | "start: %lu, end: %lu\n", |
@@ -730,7 +730,7 @@ find_next_usable_block(ext3_grpblk_t start, struct buffer_head *bh, | |||
730 | here = 0; | 730 | here = 0; |
731 | 731 | ||
732 | p = ((char *)bh->b_data) + (here >> 3); | 732 | p = ((char *)bh->b_data) + (here >> 3); |
733 | r = memscan(p, 0, (maxblocks - here + 7) >> 3); | 733 | r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); |
734 | next = (r - ((char *)bh->b_data)) << 3; | 734 | next = (r - ((char *)bh->b_data)) << 3; |
735 | 735 | ||
736 | if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh)) | 736 | if (next < maxblocks && next >= start && ext3_test_allocatable(next, bh)) |
@@ -949,7 +949,7 @@ static int find_next_reservable_window( | |||
949 | 949 | ||
950 | prev = rsv; | 950 | prev = rsv; |
951 | next = rb_next(&rsv->rsv_node); | 951 | next = rb_next(&rsv->rsv_node); |
952 | rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node); | 952 | rsv = rb_entry(next,struct ext3_reserve_window_node,rsv_node); |
953 | 953 | ||
954 | /* | 954 | /* |
955 | * Reached the last reservation, we can just append to the | 955 | * Reached the last reservation, we can just append to the |
@@ -1148,7 +1148,7 @@ retry: | |||
1148 | * check if the first free block is within the | 1148 | * check if the first free block is within the |
1149 | * free space we just reserved | 1149 | * free space we just reserved |
1150 | */ | 1150 | */ |
1151 | if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) | 1151 | if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end) |
1152 | return 0; /* success */ | 1152 | return 0; /* success */ |
1153 | /* | 1153 | /* |
1154 | * if the first free bit we found is out of the reservable space | 1154 | * if the first free bit we found is out of the reservable space |
@@ -1193,7 +1193,7 @@ static void try_to_extend_reservation(struct ext3_reserve_window_node *my_rsv, | |||
1193 | if (!next) | 1193 | if (!next) |
1194 | my_rsv->rsv_end += size; | 1194 | my_rsv->rsv_end += size; |
1195 | else { | 1195 | else { |
1196 | next_rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node); | 1196 | next_rsv = rb_entry(next, struct ext3_reserve_window_node, rsv_node); |
1197 | 1197 | ||
1198 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) | 1198 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) |
1199 | my_rsv->rsv_end += size; | 1199 | my_rsv->rsv_end += size; |
@@ -1271,7 +1271,7 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1271 | } | 1271 | } |
1272 | /* | 1272 | /* |
1273 | * grp_goal is a group relative block number (if there is a goal) | 1273 | * grp_goal is a group relative block number (if there is a goal) |
1274 | * 0 < grp_goal < EXT3_BLOCKS_PER_GROUP(sb) | 1274 | * 0 <= grp_goal < EXT3_BLOCKS_PER_GROUP(sb) |
1275 | * first block is a filesystem wide block number | 1275 | * first block is a filesystem wide block number |
1276 | * first block is the block number of the first block in this group | 1276 | * first block is the block number of the first block in this group |
1277 | */ | 1277 | */ |
@@ -1307,10 +1307,14 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1307 | if (!goal_in_my_reservation(&my_rsv->rsv_window, | 1307 | if (!goal_in_my_reservation(&my_rsv->rsv_window, |
1308 | grp_goal, group, sb)) | 1308 | grp_goal, group, sb)) |
1309 | grp_goal = -1; | 1309 | grp_goal = -1; |
1310 | } else if (grp_goal > 0 && | 1310 | } else if (grp_goal >= 0) { |
1311 | (my_rsv->rsv_end-grp_goal+1) < *count) | 1311 | int curr = my_rsv->rsv_end - |
1312 | try_to_extend_reservation(my_rsv, sb, | 1312 | (grp_goal + group_first_block) + 1; |
1313 | *count-my_rsv->rsv_end + grp_goal - 1); | 1313 | |
1314 | if (curr < *count) | ||
1315 | try_to_extend_reservation(my_rsv, sb, | ||
1316 | *count - curr); | ||
1317 | } | ||
1314 | 1318 | ||
1315 | if ((my_rsv->rsv_start > group_last_block) || | 1319 | if ((my_rsv->rsv_start > group_last_block) || |
1316 | (my_rsv->rsv_end < group_first_block)) { | 1320 | (my_rsv->rsv_end < group_first_block)) { |
@@ -1511,10 +1515,8 @@ retry_alloc: | |||
1511 | if (group_no >= ngroups) | 1515 | if (group_no >= ngroups) |
1512 | group_no = 0; | 1516 | group_no = 0; |
1513 | gdp = ext3_get_group_desc(sb, group_no, &gdp_bh); | 1517 | gdp = ext3_get_group_desc(sb, group_no, &gdp_bh); |
1514 | if (!gdp) { | 1518 | if (!gdp) |
1515 | *errp = -EIO; | 1519 | goto io_error; |
1516 | goto out; | ||
1517 | } | ||
1518 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); | 1520 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); |
1519 | /* | 1521 | /* |
1520 | * skip this group if the number of | 1522 | * skip this group if the number of |
@@ -1548,6 +1550,7 @@ retry_alloc: | |||
1548 | */ | 1550 | */ |
1549 | if (my_rsv) { | 1551 | if (my_rsv) { |
1550 | my_rsv = NULL; | 1552 | my_rsv = NULL; |
1553 | windowsz = 0; | ||
1551 | group_no = goal_group; | 1554 | group_no = goal_group; |
1552 | goto retry_alloc; | 1555 | goto retry_alloc; |
1553 | } | 1556 | } |
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index d0b54f30b914..5a9313ecd4ef 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -154,6 +154,9 @@ static int ext3_readdir(struct file * filp, | |||
154 | ext3_error (sb, "ext3_readdir", | 154 | ext3_error (sb, "ext3_readdir", |
155 | "directory #%lu contains a hole at offset %lu", | 155 | "directory #%lu contains a hole at offset %lu", |
156 | inode->i_ino, (unsigned long)filp->f_pos); | 156 | inode->i_ino, (unsigned long)filp->f_pos); |
157 | /* corrupt size? Maybe no more blocks to read */ | ||
158 | if (filp->f_pos > inode->i_blocks << 9) | ||
159 | break; | ||
157 | filp->f_pos += sb->s_blocksize - offset; | 160 | filp->f_pos += sb->s_blocksize - offset; |
158 | continue; | 161 | continue; |
159 | } | 162 | } |
diff --git a/fs/ext3/ext3_jbd.c b/fs/ext3/ext3_jbd.c new file mode 100644 index 000000000000..e1f91fd26a93 --- /dev/null +++ b/fs/ext3/ext3_jbd.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Interface between ext3 and JBD | ||
3 | */ | ||
4 | |||
5 | #include <linux/ext3_jbd.h> | ||
6 | |||
7 | int __ext3_journal_get_undo_access(const char *where, handle_t *handle, | ||
8 | struct buffer_head *bh) | ||
9 | { | ||
10 | int err = journal_get_undo_access(handle, bh); | ||
11 | if (err) | ||
12 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
13 | return err; | ||
14 | } | ||
15 | |||
16 | int __ext3_journal_get_write_access(const char *where, handle_t *handle, | ||
17 | struct buffer_head *bh) | ||
18 | { | ||
19 | int err = journal_get_write_access(handle, bh); | ||
20 | if (err) | ||
21 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
22 | return err; | ||
23 | } | ||
24 | |||
25 | int __ext3_journal_forget(const char *where, handle_t *handle, | ||
26 | struct buffer_head *bh) | ||
27 | { | ||
28 | int err = journal_forget(handle, bh); | ||
29 | if (err) | ||
30 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
31 | return err; | ||
32 | } | ||
33 | |||
34 | int __ext3_journal_revoke(const char *where, handle_t *handle, | ||
35 | unsigned long blocknr, struct buffer_head *bh) | ||
36 | { | ||
37 | int err = journal_revoke(handle, blocknr, bh); | ||
38 | if (err) | ||
39 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
40 | return err; | ||
41 | } | ||
42 | |||
43 | int __ext3_journal_get_create_access(const char *where, | ||
44 | handle_t *handle, struct buffer_head *bh) | ||
45 | { | ||
46 | int err = journal_get_create_access(handle, bh); | ||
47 | if (err) | ||
48 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | int __ext3_journal_dirty_metadata(const char *where, | ||
53 | handle_t *handle, struct buffer_head *bh) | ||
54 | { | ||
55 | int err = journal_dirty_metadata(handle, bh); | ||
56 | if (err) | ||
57 | ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
58 | return err; | ||
59 | } | ||
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 03ba5bcab186..beaf25f5112f 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1148,37 +1148,102 @@ static int do_journal_get_write_access(handle_t *handle, | |||
1148 | return ext3_journal_get_write_access(handle, bh); | 1148 | return ext3_journal_get_write_access(handle, bh); |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | /* | ||
1152 | * The idea of this helper function is following: | ||
1153 | * if prepare_write has allocated some blocks, but not all of them, the | ||
1154 | * transaction must include the content of the newly allocated blocks. | ||
1155 | * This content is expected to be set to zeroes by block_prepare_write(). | ||
1156 | * 2006/10/14 SAW | ||
1157 | */ | ||
1158 | static int ext3_prepare_failure(struct file *file, struct page *page, | ||
1159 | unsigned from, unsigned to) | ||
1160 | { | ||
1161 | struct address_space *mapping; | ||
1162 | struct buffer_head *bh, *head, *next; | ||
1163 | unsigned block_start, block_end; | ||
1164 | unsigned blocksize; | ||
1165 | int ret; | ||
1166 | handle_t *handle = ext3_journal_current_handle(); | ||
1167 | |||
1168 | mapping = page->mapping; | ||
1169 | if (ext3_should_writeback_data(mapping->host)) { | ||
1170 | /* optimization: no constraints about data */ | ||
1171 | skip: | ||
1172 | return ext3_journal_stop(handle); | ||
1173 | } | ||
1174 | |||
1175 | head = page_buffers(page); | ||
1176 | blocksize = head->b_size; | ||
1177 | for ( bh = head, block_start = 0; | ||
1178 | bh != head || !block_start; | ||
1179 | block_start = block_end, bh = next) | ||
1180 | { | ||
1181 | next = bh->b_this_page; | ||
1182 | block_end = block_start + blocksize; | ||
1183 | if (block_end <= from) | ||
1184 | continue; | ||
1185 | if (block_start >= to) { | ||
1186 | block_start = to; | ||
1187 | break; | ||
1188 | } | ||
1189 | if (!buffer_mapped(bh)) | ||
1190 | /* prepare_write failed on this bh */ | ||
1191 | break; | ||
1192 | if (ext3_should_journal_data(mapping->host)) { | ||
1193 | ret = do_journal_get_write_access(handle, bh); | ||
1194 | if (ret) { | ||
1195 | ext3_journal_stop(handle); | ||
1196 | return ret; | ||
1197 | } | ||
1198 | } | ||
1199 | /* | ||
1200 | * block_start here becomes the first block where the current iteration | ||
1201 | * of prepare_write failed. | ||
1202 | */ | ||
1203 | } | ||
1204 | if (block_start <= from) | ||
1205 | goto skip; | ||
1206 | |||
1207 | /* commit allocated and zeroed buffers */ | ||
1208 | return mapping->a_ops->commit_write(file, page, from, block_start); | ||
1209 | } | ||
1210 | |||
1151 | static int ext3_prepare_write(struct file *file, struct page *page, | 1211 | static int ext3_prepare_write(struct file *file, struct page *page, |
1152 | unsigned from, unsigned to) | 1212 | unsigned from, unsigned to) |
1153 | { | 1213 | { |
1154 | struct inode *inode = page->mapping->host; | 1214 | struct inode *inode = page->mapping->host; |
1155 | int ret, needed_blocks = ext3_writepage_trans_blocks(inode); | 1215 | int ret, ret2; |
1216 | int needed_blocks = ext3_writepage_trans_blocks(inode); | ||
1156 | handle_t *handle; | 1217 | handle_t *handle; |
1157 | int retries = 0; | 1218 | int retries = 0; |
1158 | 1219 | ||
1159 | retry: | 1220 | retry: |
1160 | handle = ext3_journal_start(inode, needed_blocks); | 1221 | handle = ext3_journal_start(inode, needed_blocks); |
1161 | if (IS_ERR(handle)) { | 1222 | if (IS_ERR(handle)) |
1162 | ret = PTR_ERR(handle); | 1223 | return PTR_ERR(handle); |
1163 | goto out; | ||
1164 | } | ||
1165 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) | 1224 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) |
1166 | ret = nobh_prepare_write(page, from, to, ext3_get_block); | 1225 | ret = nobh_prepare_write(page, from, to, ext3_get_block); |
1167 | else | 1226 | else |
1168 | ret = block_prepare_write(page, from, to, ext3_get_block); | 1227 | ret = block_prepare_write(page, from, to, ext3_get_block); |
1169 | if (ret) | 1228 | if (ret) |
1170 | goto prepare_write_failed; | 1229 | goto failure; |
1171 | 1230 | ||
1172 | if (ext3_should_journal_data(inode)) { | 1231 | if (ext3_should_journal_data(inode)) { |
1173 | ret = walk_page_buffers(handle, page_buffers(page), | 1232 | ret = walk_page_buffers(handle, page_buffers(page), |
1174 | from, to, NULL, do_journal_get_write_access); | 1233 | from, to, NULL, do_journal_get_write_access); |
1234 | if (ret) | ||
1235 | /* fatal error, just put the handle and return */ | ||
1236 | journal_stop(handle); | ||
1175 | } | 1237 | } |
1176 | prepare_write_failed: | 1238 | return ret; |
1177 | if (ret) | 1239 | |
1178 | ext3_journal_stop(handle); | 1240 | failure: |
1241 | ret2 = ext3_prepare_failure(file, page, from, to); | ||
1242 | if (ret2 < 0) | ||
1243 | return ret2; | ||
1179 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | 1244 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) |
1180 | goto retry; | 1245 | goto retry; |
1181 | out: | 1246 | /* retry number exceeded, or other error like -EDQUOT */ |
1182 | return ret; | 1247 | return ret; |
1183 | } | 1248 | } |
1184 | 1249 | ||
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 906731a20f1a..60d2f9dbdb00 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -552,6 +552,15 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
552 | dir->i_sb->s_blocksize - | 552 | dir->i_sb->s_blocksize - |
553 | EXT3_DIR_REC_LEN(0)); | 553 | EXT3_DIR_REC_LEN(0)); |
554 | for (; de < top; de = ext3_next_entry(de)) { | 554 | for (; de < top; de = ext3_next_entry(de)) { |
555 | if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, | ||
556 | (block<<EXT3_BLOCK_SIZE_BITS(dir->i_sb)) | ||
557 | +((char *)de - bh->b_data))) { | ||
558 | /* On error, skip the f_pos to the next block. */ | ||
559 | dir_file->f_pos = (dir_file->f_pos | | ||
560 | (dir->i_sb->s_blocksize - 1)) + 1; | ||
561 | brelse (bh); | ||
562 | return count; | ||
563 | } | ||
555 | ext3fs_dirhash(de->name, de->name_len, hinfo); | 564 | ext3fs_dirhash(de->name, de->name_len, hinfo); |
556 | if ((hinfo->hash < start_hash) || | 565 | if ((hinfo->hash < start_hash) || |
557 | ((hinfo->hash == start_hash) && | 566 | ((hinfo->hash == start_hash) && |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index afc2d4f42d77..580b8a6ca979 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -436,7 +436,7 @@ static void ext3_put_super (struct super_block * sb) | |||
436 | return; | 436 | return; |
437 | } | 437 | } |
438 | 438 | ||
439 | static kmem_cache_t *ext3_inode_cachep; | 439 | static struct kmem_cache *ext3_inode_cachep; |
440 | 440 | ||
441 | /* | 441 | /* |
442 | * Called inside transaction, so use GFP_NOFS | 442 | * Called inside transaction, so use GFP_NOFS |
@@ -445,7 +445,7 @@ static struct inode *ext3_alloc_inode(struct super_block *sb) | |||
445 | { | 445 | { |
446 | struct ext3_inode_info *ei; | 446 | struct ext3_inode_info *ei; |
447 | 447 | ||
448 | ei = kmem_cache_alloc(ext3_inode_cachep, SLAB_NOFS); | 448 | ei = kmem_cache_alloc(ext3_inode_cachep, GFP_NOFS); |
449 | if (!ei) | 449 | if (!ei) |
450 | return NULL; | 450 | return NULL; |
451 | #ifdef CONFIG_EXT3_FS_POSIX_ACL | 451 | #ifdef CONFIG_EXT3_FS_POSIX_ACL |
@@ -462,7 +462,7 @@ static void ext3_destroy_inode(struct inode *inode) | |||
462 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); | 462 | kmem_cache_free(ext3_inode_cachep, EXT3_I(inode)); |
463 | } | 463 | } |
464 | 464 | ||
465 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 465 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
466 | { | 466 | { |
467 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; | 467 | struct ext3_inode_info *ei = (struct ext3_inode_info *) foo; |
468 | 468 | ||
@@ -1264,6 +1264,12 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1264 | return; | 1264 | return; |
1265 | } | 1265 | } |
1266 | 1266 | ||
1267 | if (bdev_read_only(sb->s_bdev)) { | ||
1268 | printk(KERN_ERR "EXT3-fs: write access " | ||
1269 | "unavailable, skipping orphan cleanup.\n"); | ||
1270 | return; | ||
1271 | } | ||
1272 | |||
1267 | if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { | 1273 | if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { |
1268 | if (es->s_last_orphan) | 1274 | if (es->s_last_orphan) |
1269 | jbd_debug(1, "Errors on filesystem, " | 1275 | jbd_debug(1, "Errors on filesystem, " |
@@ -2387,6 +2393,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2387 | struct ext3_super_block *es = sbi->s_es; | 2393 | struct ext3_super_block *es = sbi->s_es; |
2388 | ext3_fsblk_t overhead; | 2394 | ext3_fsblk_t overhead; |
2389 | int i; | 2395 | int i; |
2396 | u64 fsid; | ||
2390 | 2397 | ||
2391 | if (test_opt (sb, MINIX_DF)) | 2398 | if (test_opt (sb, MINIX_DF)) |
2392 | overhead = 0; | 2399 | overhead = 0; |
@@ -2433,6 +2440,10 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2433 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2440 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2434 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2441 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2435 | buf->f_namelen = EXT3_NAME_LEN; | 2442 | buf->f_namelen = EXT3_NAME_LEN; |
2443 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | ||
2444 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | ||
2445 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; | ||
2446 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; | ||
2436 | return 0; | 2447 | return 0; |
2437 | } | 2448 | } |
2438 | 2449 | ||
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index f86f2482f01d..99857a400f4b 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -459,14 +459,11 @@ static void ext3_xattr_update_super_block(handle_t *handle, | |||
459 | if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) | 459 | if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) |
460 | return; | 460 | return; |
461 | 461 | ||
462 | lock_super(sb); | ||
463 | if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) { | 462 | if (ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh) == 0) { |
464 | EXT3_SB(sb)->s_es->s_feature_compat |= | 463 | EXT3_SET_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR); |
465 | cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); | ||
466 | sb->s_dirt = 1; | 464 | sb->s_dirt = 1; |
467 | ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); | 465 | ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); |
468 | } | 466 | } |
469 | unlock_super(sb); | ||
470 | } | 467 | } |
471 | 468 | ||
472 | /* | 469 | /* |
diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index a6acb96ebeb9..ae6e7e502ac9 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile | |||
@@ -5,7 +5,8 @@ | |||
5 | obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o | 5 | obj-$(CONFIG_EXT4DEV_FS) += ext4dev.o |
6 | 6 | ||
7 | ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ | 7 | ext4dev-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ |
8 | ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o | 8 | ioctl.o namei.o super.o symlink.o hash.o resize.o extents.o \ |
9 | ext4_jbd2.o | ||
9 | 10 | ||
10 | ext4dev-$(CONFIG_EXT4DEV_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o | 11 | ext4dev-$(CONFIG_EXT4DEV_FS_XATTR) += xattr.o xattr_user.o xattr_trusted.o |
11 | ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o | 12 | ext4dev-$(CONFIG_EXT4DEV_FS_POSIX_ACL) += acl.o |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 5d45582f9517..c4dd1103ccf1 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -165,7 +165,7 @@ restart: | |||
165 | 165 | ||
166 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); | 166 | printk("Block Allocation Reservation Windows Map (%s):\n", fn); |
167 | while (n) { | 167 | while (n) { |
168 | rsv = list_entry(n, struct ext4_reserve_window_node, rsv_node); | 168 | rsv = rb_entry(n, struct ext4_reserve_window_node, rsv_node); |
169 | if (verbose) | 169 | if (verbose) |
170 | printk("reservation window 0x%p " | 170 | printk("reservation window 0x%p " |
171 | "start: %llu, end: %llu\n", | 171 | "start: %llu, end: %llu\n", |
@@ -747,7 +747,7 @@ find_next_usable_block(ext4_grpblk_t start, struct buffer_head *bh, | |||
747 | here = 0; | 747 | here = 0; |
748 | 748 | ||
749 | p = ((char *)bh->b_data) + (here >> 3); | 749 | p = ((char *)bh->b_data) + (here >> 3); |
750 | r = memscan(p, 0, (maxblocks - here + 7) >> 3); | 750 | r = memscan(p, 0, ((maxblocks + 7) >> 3) - (here >> 3)); |
751 | next = (r - ((char *)bh->b_data)) << 3; | 751 | next = (r - ((char *)bh->b_data)) << 3; |
752 | 752 | ||
753 | if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh)) | 753 | if (next < maxblocks && next >= start && ext4_test_allocatable(next, bh)) |
@@ -966,7 +966,7 @@ static int find_next_reservable_window( | |||
966 | 966 | ||
967 | prev = rsv; | 967 | prev = rsv; |
968 | next = rb_next(&rsv->rsv_node); | 968 | next = rb_next(&rsv->rsv_node); |
969 | rsv = list_entry(next,struct ext4_reserve_window_node,rsv_node); | 969 | rsv = rb_entry(next,struct ext4_reserve_window_node,rsv_node); |
970 | 970 | ||
971 | /* | 971 | /* |
972 | * Reached the last reservation, we can just append to the | 972 | * Reached the last reservation, we can just append to the |
@@ -1165,7 +1165,7 @@ retry: | |||
1165 | * check if the first free block is within the | 1165 | * check if the first free block is within the |
1166 | * free space we just reserved | 1166 | * free space we just reserved |
1167 | */ | 1167 | */ |
1168 | if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) | 1168 | if (start_block >= my_rsv->rsv_start && start_block <= my_rsv->rsv_end) |
1169 | return 0; /* success */ | 1169 | return 0; /* success */ |
1170 | /* | 1170 | /* |
1171 | * if the first free bit we found is out of the reservable space | 1171 | * if the first free bit we found is out of the reservable space |
@@ -1210,7 +1210,7 @@ static void try_to_extend_reservation(struct ext4_reserve_window_node *my_rsv, | |||
1210 | if (!next) | 1210 | if (!next) |
1211 | my_rsv->rsv_end += size; | 1211 | my_rsv->rsv_end += size; |
1212 | else { | 1212 | else { |
1213 | next_rsv = list_entry(next, struct ext4_reserve_window_node, rsv_node); | 1213 | next_rsv = rb_entry(next, struct ext4_reserve_window_node, rsv_node); |
1214 | 1214 | ||
1215 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) | 1215 | if ((next_rsv->rsv_start - my_rsv->rsv_end - 1) >= size) |
1216 | my_rsv->rsv_end += size; | 1216 | my_rsv->rsv_end += size; |
@@ -1288,7 +1288,7 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1288 | } | 1288 | } |
1289 | /* | 1289 | /* |
1290 | * grp_goal is a group relative block number (if there is a goal) | 1290 | * grp_goal is a group relative block number (if there is a goal) |
1291 | * 0 < grp_goal < EXT4_BLOCKS_PER_GROUP(sb) | 1291 | * 0 <= grp_goal < EXT4_BLOCKS_PER_GROUP(sb) |
1292 | * first block is a filesystem wide block number | 1292 | * first block is a filesystem wide block number |
1293 | * first block is the block number of the first block in this group | 1293 | * first block is the block number of the first block in this group |
1294 | */ | 1294 | */ |
@@ -1324,10 +1324,14 @@ ext4_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, | |||
1324 | if (!goal_in_my_reservation(&my_rsv->rsv_window, | 1324 | if (!goal_in_my_reservation(&my_rsv->rsv_window, |
1325 | grp_goal, group, sb)) | 1325 | grp_goal, group, sb)) |
1326 | grp_goal = -1; | 1326 | grp_goal = -1; |
1327 | } else if (grp_goal > 0 && | 1327 | } else if (grp_goal >= 0) { |
1328 | (my_rsv->rsv_end-grp_goal+1) < *count) | 1328 | int curr = my_rsv->rsv_end - |
1329 | try_to_extend_reservation(my_rsv, sb, | 1329 | (grp_goal + group_first_block) + 1; |
1330 | *count-my_rsv->rsv_end + grp_goal - 1); | 1330 | |
1331 | if (curr < *count) | ||
1332 | try_to_extend_reservation(my_rsv, sb, | ||
1333 | *count - curr); | ||
1334 | } | ||
1331 | 1335 | ||
1332 | if ((my_rsv->rsv_start > group_last_block) || | 1336 | if ((my_rsv->rsv_start > group_last_block) || |
1333 | (my_rsv->rsv_end < group_first_block)) { | 1337 | (my_rsv->rsv_end < group_first_block)) { |
@@ -1525,10 +1529,8 @@ retry_alloc: | |||
1525 | if (group_no >= ngroups) | 1529 | if (group_no >= ngroups) |
1526 | group_no = 0; | 1530 | group_no = 0; |
1527 | gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); | 1531 | gdp = ext4_get_group_desc(sb, group_no, &gdp_bh); |
1528 | if (!gdp) { | 1532 | if (!gdp) |
1529 | *errp = -EIO; | 1533 | goto io_error; |
1530 | goto out; | ||
1531 | } | ||
1532 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); | 1534 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); |
1533 | /* | 1535 | /* |
1534 | * skip this group if the number of | 1536 | * skip this group if the number of |
@@ -1562,6 +1564,7 @@ retry_alloc: | |||
1562 | */ | 1564 | */ |
1563 | if (my_rsv) { | 1565 | if (my_rsv) { |
1564 | my_rsv = NULL; | 1566 | my_rsv = NULL; |
1567 | windowsz = 0; | ||
1565 | group_no = goal_group; | 1568 | group_no = goal_group; |
1566 | goto retry_alloc; | 1569 | goto retry_alloc; |
1567 | } | 1570 | } |
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index f8595787a70e..f2ed3e7fb9f5 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c | |||
@@ -153,6 +153,9 @@ static int ext4_readdir(struct file * filp, | |||
153 | ext4_error (sb, "ext4_readdir", | 153 | ext4_error (sb, "ext4_readdir", |
154 | "directory #%lu contains a hole at offset %lu", | 154 | "directory #%lu contains a hole at offset %lu", |
155 | inode->i_ino, (unsigned long)filp->f_pos); | 155 | inode->i_ino, (unsigned long)filp->f_pos); |
156 | /* corrupt size? Maybe no more blocks to read */ | ||
157 | if (filp->f_pos > inode->i_blocks << 9) | ||
158 | break; | ||
156 | filp->f_pos += sb->s_blocksize - offset; | 159 | filp->f_pos += sb->s_blocksize - offset; |
157 | continue; | 160 | continue; |
158 | } | 161 | } |
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c new file mode 100644 index 000000000000..d6afe4e27340 --- /dev/null +++ b/fs/ext4/ext4_jbd2.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Interface between ext4 and JBD | ||
3 | */ | ||
4 | |||
5 | #include <linux/ext4_jbd2.h> | ||
6 | |||
7 | int __ext4_journal_get_undo_access(const char *where, handle_t *handle, | ||
8 | struct buffer_head *bh) | ||
9 | { | ||
10 | int err = jbd2_journal_get_undo_access(handle, bh); | ||
11 | if (err) | ||
12 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
13 | return err; | ||
14 | } | ||
15 | |||
16 | int __ext4_journal_get_write_access(const char *where, handle_t *handle, | ||
17 | struct buffer_head *bh) | ||
18 | { | ||
19 | int err = jbd2_journal_get_write_access(handle, bh); | ||
20 | if (err) | ||
21 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
22 | return err; | ||
23 | } | ||
24 | |||
25 | int __ext4_journal_forget(const char *where, handle_t *handle, | ||
26 | struct buffer_head *bh) | ||
27 | { | ||
28 | int err = jbd2_journal_forget(handle, bh); | ||
29 | if (err) | ||
30 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
31 | return err; | ||
32 | } | ||
33 | |||
34 | int __ext4_journal_revoke(const char *where, handle_t *handle, | ||
35 | ext4_fsblk_t blocknr, struct buffer_head *bh) | ||
36 | { | ||
37 | int err = jbd2_journal_revoke(handle, blocknr, bh); | ||
38 | if (err) | ||
39 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
40 | return err; | ||
41 | } | ||
42 | |||
43 | int __ext4_journal_get_create_access(const char *where, | ||
44 | handle_t *handle, struct buffer_head *bh) | ||
45 | { | ||
46 | int err = jbd2_journal_get_create_access(handle, bh); | ||
47 | if (err) | ||
48 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
49 | return err; | ||
50 | } | ||
51 | |||
52 | int __ext4_journal_dirty_metadata(const char *where, | ||
53 | handle_t *handle, struct buffer_head *bh) | ||
54 | { | ||
55 | int err = jbd2_journal_dirty_metadata(handle, bh); | ||
56 | if (err) | ||
57 | ext4_journal_abort_handle(where, __FUNCTION__, bh, handle,err); | ||
58 | return err; | ||
59 | } | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 2608dce18f3e..dc2724fa7622 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -48,7 +48,7 @@ | |||
48 | * ext_pblock: | 48 | * ext_pblock: |
49 | * combine low and high parts of physical block number into ext4_fsblk_t | 49 | * combine low and high parts of physical block number into ext4_fsblk_t |
50 | */ | 50 | */ |
51 | static inline ext4_fsblk_t ext_pblock(struct ext4_extent *ex) | 51 | static ext4_fsblk_t ext_pblock(struct ext4_extent *ex) |
52 | { | 52 | { |
53 | ext4_fsblk_t block; | 53 | ext4_fsblk_t block; |
54 | 54 | ||
@@ -61,7 +61,7 @@ static inline ext4_fsblk_t ext_pblock(struct ext4_extent *ex) | |||
61 | * idx_pblock: | 61 | * idx_pblock: |
62 | * combine low and high parts of a leaf physical block number into ext4_fsblk_t | 62 | * combine low and high parts of a leaf physical block number into ext4_fsblk_t |
63 | */ | 63 | */ |
64 | static inline ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) | 64 | static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) |
65 | { | 65 | { |
66 | ext4_fsblk_t block; | 66 | ext4_fsblk_t block; |
67 | 67 | ||
@@ -75,7 +75,7 @@ static inline ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) | |||
75 | * stores a large physical block number into an extent struct, | 75 | * stores a large physical block number into an extent struct, |
76 | * breaking it into parts | 76 | * breaking it into parts |
77 | */ | 77 | */ |
78 | static inline void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) | 78 | static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) |
79 | { | 79 | { |
80 | ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff)); | 80 | ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff)); |
81 | ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | 81 | ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); |
@@ -86,7 +86,7 @@ static inline void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb | |||
86 | * stores a large physical block number into an index struct, | 86 | * stores a large physical block number into an index struct, |
87 | * breaking it into parts | 87 | * breaking it into parts |
88 | */ | 88 | */ |
89 | static inline void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) | 89 | static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) |
90 | { | 90 | { |
91 | ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff)); | 91 | ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff)); |
92 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); | 92 | ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); |
@@ -186,7 +186,8 @@ static ext4_fsblk_t ext4_ext_find_goal(struct inode *inode, | |||
186 | depth = path->p_depth; | 186 | depth = path->p_depth; |
187 | 187 | ||
188 | /* try to predict block placement */ | 188 | /* try to predict block placement */ |
189 | if ((ex = path[depth].p_ext)) | 189 | ex = path[depth].p_ext; |
190 | if (ex) | ||
190 | return ext_pblock(ex)+(block-le32_to_cpu(ex->ee_block)); | 191 | return ext_pblock(ex)+(block-le32_to_cpu(ex->ee_block)); |
191 | 192 | ||
192 | /* it looks like index is empty; | 193 | /* it looks like index is empty; |
@@ -215,7 +216,7 @@ ext4_ext_new_block(handle_t *handle, struct inode *inode, | |||
215 | return newblock; | 216 | return newblock; |
216 | } | 217 | } |
217 | 218 | ||
218 | static inline int ext4_ext_space_block(struct inode *inode) | 219 | static int ext4_ext_space_block(struct inode *inode) |
219 | { | 220 | { |
220 | int size; | 221 | int size; |
221 | 222 | ||
@@ -228,7 +229,7 @@ static inline int ext4_ext_space_block(struct inode *inode) | |||
228 | return size; | 229 | return size; |
229 | } | 230 | } |
230 | 231 | ||
231 | static inline int ext4_ext_space_block_idx(struct inode *inode) | 232 | static int ext4_ext_space_block_idx(struct inode *inode) |
232 | { | 233 | { |
233 | int size; | 234 | int size; |
234 | 235 | ||
@@ -241,7 +242,7 @@ static inline int ext4_ext_space_block_idx(struct inode *inode) | |||
241 | return size; | 242 | return size; |
242 | } | 243 | } |
243 | 244 | ||
244 | static inline int ext4_ext_space_root(struct inode *inode) | 245 | static int ext4_ext_space_root(struct inode *inode) |
245 | { | 246 | { |
246 | int size; | 247 | int size; |
247 | 248 | ||
@@ -255,7 +256,7 @@ static inline int ext4_ext_space_root(struct inode *inode) | |||
255 | return size; | 256 | return size; |
256 | } | 257 | } |
257 | 258 | ||
258 | static inline int ext4_ext_space_root_idx(struct inode *inode) | 259 | static int ext4_ext_space_root_idx(struct inode *inode) |
259 | { | 260 | { |
260 | int size; | 261 | int size; |
261 | 262 | ||
@@ -476,13 +477,12 @@ ext4_ext_find_extent(struct inode *inode, int block, struct ext4_ext_path *path) | |||
476 | 477 | ||
477 | /* account possible depth increase */ | 478 | /* account possible depth increase */ |
478 | if (!path) { | 479 | if (!path) { |
479 | path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 2), | 480 | path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 2), |
480 | GFP_NOFS); | 481 | GFP_NOFS); |
481 | if (!path) | 482 | if (!path) |
482 | return ERR_PTR(-ENOMEM); | 483 | return ERR_PTR(-ENOMEM); |
483 | alloc = 1; | 484 | alloc = 1; |
484 | } | 485 | } |
485 | memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1)); | ||
486 | path[0].p_hdr = eh; | 486 | path[0].p_hdr = eh; |
487 | 487 | ||
488 | /* walk through the tree */ | 488 | /* walk through the tree */ |
@@ -543,7 +543,8 @@ static int ext4_ext_insert_index(handle_t *handle, struct inode *inode, | |||
543 | struct ext4_extent_idx *ix; | 543 | struct ext4_extent_idx *ix; |
544 | int len, err; | 544 | int len, err; |
545 | 545 | ||
546 | if ((err = ext4_ext_get_access(handle, inode, curp))) | 546 | err = ext4_ext_get_access(handle, inode, curp); |
547 | if (err) | ||
547 | return err; | 548 | return err; |
548 | 549 | ||
549 | BUG_ON(logical == le32_to_cpu(curp->p_idx->ei_block)); | 550 | BUG_ON(logical == le32_to_cpu(curp->p_idx->ei_block)); |
@@ -641,10 +642,9 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
641 | * We need this to handle errors and free blocks | 642 | * We need this to handle errors and free blocks |
642 | * upon them. | 643 | * upon them. |
643 | */ | 644 | */ |
644 | ablocks = kmalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS); | 645 | ablocks = kzalloc(sizeof(ext4_fsblk_t) * depth, GFP_NOFS); |
645 | if (!ablocks) | 646 | if (!ablocks) |
646 | return -ENOMEM; | 647 | return -ENOMEM; |
647 | memset(ablocks, 0, sizeof(ext4_fsblk_t) * depth); | ||
648 | 648 | ||
649 | /* allocate all needed blocks */ | 649 | /* allocate all needed blocks */ |
650 | ext_debug("allocate %d blocks for indexes/leaf\n", depth - at); | 650 | ext_debug("allocate %d blocks for indexes/leaf\n", depth - at); |
@@ -665,7 +665,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
665 | } | 665 | } |
666 | lock_buffer(bh); | 666 | lock_buffer(bh); |
667 | 667 | ||
668 | if ((err = ext4_journal_get_create_access(handle, bh))) | 668 | err = ext4_journal_get_create_access(handle, bh); |
669 | if (err) | ||
669 | goto cleanup; | 670 | goto cleanup; |
670 | 671 | ||
671 | neh = ext_block_hdr(bh); | 672 | neh = ext_block_hdr(bh); |
@@ -702,18 +703,21 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
702 | set_buffer_uptodate(bh); | 703 | set_buffer_uptodate(bh); |
703 | unlock_buffer(bh); | 704 | unlock_buffer(bh); |
704 | 705 | ||
705 | if ((err = ext4_journal_dirty_metadata(handle, bh))) | 706 | err = ext4_journal_dirty_metadata(handle, bh); |
707 | if (err) | ||
706 | goto cleanup; | 708 | goto cleanup; |
707 | brelse(bh); | 709 | brelse(bh); |
708 | bh = NULL; | 710 | bh = NULL; |
709 | 711 | ||
710 | /* correct old leaf */ | 712 | /* correct old leaf */ |
711 | if (m) { | 713 | if (m) { |
712 | if ((err = ext4_ext_get_access(handle, inode, path + depth))) | 714 | err = ext4_ext_get_access(handle, inode, path + depth); |
715 | if (err) | ||
713 | goto cleanup; | 716 | goto cleanup; |
714 | path[depth].p_hdr->eh_entries = | 717 | path[depth].p_hdr->eh_entries = |
715 | cpu_to_le16(le16_to_cpu(path[depth].p_hdr->eh_entries)-m); | 718 | cpu_to_le16(le16_to_cpu(path[depth].p_hdr->eh_entries)-m); |
716 | if ((err = ext4_ext_dirty(handle, inode, path + depth))) | 719 | err = ext4_ext_dirty(handle, inode, path + depth); |
720 | if (err) | ||
717 | goto cleanup; | 721 | goto cleanup; |
718 | 722 | ||
719 | } | 723 | } |
@@ -736,7 +740,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
736 | } | 740 | } |
737 | lock_buffer(bh); | 741 | lock_buffer(bh); |
738 | 742 | ||
739 | if ((err = ext4_journal_get_create_access(handle, bh))) | 743 | err = ext4_journal_get_create_access(handle, bh); |
744 | if (err) | ||
740 | goto cleanup; | 745 | goto cleanup; |
741 | 746 | ||
742 | neh = ext_block_hdr(bh); | 747 | neh = ext_block_hdr(bh); |
@@ -780,7 +785,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
780 | set_buffer_uptodate(bh); | 785 | set_buffer_uptodate(bh); |
781 | unlock_buffer(bh); | 786 | unlock_buffer(bh); |
782 | 787 | ||
783 | if ((err = ext4_journal_dirty_metadata(handle, bh))) | 788 | err = ext4_journal_dirty_metadata(handle, bh); |
789 | if (err) | ||
784 | goto cleanup; | 790 | goto cleanup; |
785 | brelse(bh); | 791 | brelse(bh); |
786 | bh = NULL; | 792 | bh = NULL; |
@@ -800,9 +806,6 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, | |||
800 | } | 806 | } |
801 | 807 | ||
802 | /* insert new index */ | 808 | /* insert new index */ |
803 | if (err) | ||
804 | goto cleanup; | ||
805 | |||
806 | err = ext4_ext_insert_index(handle, inode, path + at, | 809 | err = ext4_ext_insert_index(handle, inode, path + at, |
807 | le32_to_cpu(border), newblock); | 810 | le32_to_cpu(border), newblock); |
808 | 811 | ||
@@ -857,7 +860,8 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | |||
857 | } | 860 | } |
858 | lock_buffer(bh); | 861 | lock_buffer(bh); |
859 | 862 | ||
860 | if ((err = ext4_journal_get_create_access(handle, bh))) { | 863 | err = ext4_journal_get_create_access(handle, bh); |
864 | if (err) { | ||
861 | unlock_buffer(bh); | 865 | unlock_buffer(bh); |
862 | goto out; | 866 | goto out; |
863 | } | 867 | } |
@@ -877,11 +881,13 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode, | |||
877 | set_buffer_uptodate(bh); | 881 | set_buffer_uptodate(bh); |
878 | unlock_buffer(bh); | 882 | unlock_buffer(bh); |
879 | 883 | ||
880 | if ((err = ext4_journal_dirty_metadata(handle, bh))) | 884 | err = ext4_journal_dirty_metadata(handle, bh); |
885 | if (err) | ||
881 | goto out; | 886 | goto out; |
882 | 887 | ||
883 | /* create index in new top-level index: num,max,pointer */ | 888 | /* create index in new top-level index: num,max,pointer */ |
884 | if ((err = ext4_ext_get_access(handle, inode, curp))) | 889 | err = ext4_ext_get_access(handle, inode, curp); |
890 | if (err) | ||
885 | goto out; | 891 | goto out; |
886 | 892 | ||
887 | curp->p_hdr->eh_magic = EXT4_EXT_MAGIC; | 893 | curp->p_hdr->eh_magic = EXT4_EXT_MAGIC; |
@@ -1073,27 +1079,31 @@ int ext4_ext_correct_indexes(handle_t *handle, struct inode *inode, | |||
1073 | */ | 1079 | */ |
1074 | k = depth - 1; | 1080 | k = depth - 1; |
1075 | border = path[depth].p_ext->ee_block; | 1081 | border = path[depth].p_ext->ee_block; |
1076 | if ((err = ext4_ext_get_access(handle, inode, path + k))) | 1082 | err = ext4_ext_get_access(handle, inode, path + k); |
1083 | if (err) | ||
1077 | return err; | 1084 | return err; |
1078 | path[k].p_idx->ei_block = border; | 1085 | path[k].p_idx->ei_block = border; |
1079 | if ((err = ext4_ext_dirty(handle, inode, path + k))) | 1086 | err = ext4_ext_dirty(handle, inode, path + k); |
1087 | if (err) | ||
1080 | return err; | 1088 | return err; |
1081 | 1089 | ||
1082 | while (k--) { | 1090 | while (k--) { |
1083 | /* change all left-side indexes */ | 1091 | /* change all left-side indexes */ |
1084 | if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr)) | 1092 | if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr)) |
1085 | break; | 1093 | break; |
1086 | if ((err = ext4_ext_get_access(handle, inode, path + k))) | 1094 | err = ext4_ext_get_access(handle, inode, path + k); |
1095 | if (err) | ||
1087 | break; | 1096 | break; |
1088 | path[k].p_idx->ei_block = border; | 1097 | path[k].p_idx->ei_block = border; |
1089 | if ((err = ext4_ext_dirty(handle, inode, path + k))) | 1098 | err = ext4_ext_dirty(handle, inode, path + k); |
1099 | if (err) | ||
1090 | break; | 1100 | break; |
1091 | } | 1101 | } |
1092 | 1102 | ||
1093 | return err; | 1103 | return err; |
1094 | } | 1104 | } |
1095 | 1105 | ||
1096 | static int inline | 1106 | static int |
1097 | ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, | 1107 | ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1, |
1098 | struct ext4_extent *ex2) | 1108 | struct ext4_extent *ex2) |
1099 | { | 1109 | { |
@@ -1145,7 +1155,8 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, | |||
1145 | le16_to_cpu(newext->ee_len), | 1155 | le16_to_cpu(newext->ee_len), |
1146 | le32_to_cpu(ex->ee_block), | 1156 | le32_to_cpu(ex->ee_block), |
1147 | le16_to_cpu(ex->ee_len), ext_pblock(ex)); | 1157 | le16_to_cpu(ex->ee_len), ext_pblock(ex)); |
1148 | if ((err = ext4_ext_get_access(handle, inode, path + depth))) | 1158 | err = ext4_ext_get_access(handle, inode, path + depth); |
1159 | if (err) | ||
1149 | return err; | 1160 | return err; |
1150 | ex->ee_len = cpu_to_le16(le16_to_cpu(ex->ee_len) | 1161 | ex->ee_len = cpu_to_le16(le16_to_cpu(ex->ee_len) |
1151 | + le16_to_cpu(newext->ee_len)); | 1162 | + le16_to_cpu(newext->ee_len)); |
@@ -1195,7 +1206,8 @@ repeat: | |||
1195 | has_space: | 1206 | has_space: |
1196 | nearex = path[depth].p_ext; | 1207 | nearex = path[depth].p_ext; |
1197 | 1208 | ||
1198 | if ((err = ext4_ext_get_access(handle, inode, path + depth))) | 1209 | err = ext4_ext_get_access(handle, inode, path + depth); |
1210 | if (err) | ||
1199 | goto cleanup; | 1211 | goto cleanup; |
1200 | 1212 | ||
1201 | if (!nearex) { | 1213 | if (!nearex) { |
@@ -1383,7 +1395,7 @@ int ext4_ext_walk_space(struct inode *inode, unsigned long block, | |||
1383 | return err; | 1395 | return err; |
1384 | } | 1396 | } |
1385 | 1397 | ||
1386 | static inline void | 1398 | static void |
1387 | ext4_ext_put_in_cache(struct inode *inode, __u32 block, | 1399 | ext4_ext_put_in_cache(struct inode *inode, __u32 block, |
1388 | __u32 len, __u32 start, int type) | 1400 | __u32 len, __u32 start, int type) |
1389 | { | 1401 | { |
@@ -1401,7 +1413,7 @@ ext4_ext_put_in_cache(struct inode *inode, __u32 block, | |||
1401 | * calculate boundaries of the gap that the requested block fits into | 1413 | * calculate boundaries of the gap that the requested block fits into |
1402 | * and cache this gap | 1414 | * and cache this gap |
1403 | */ | 1415 | */ |
1404 | static inline void | 1416 | static void |
1405 | ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | 1417 | ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, |
1406 | unsigned long block) | 1418 | unsigned long block) |
1407 | { | 1419 | { |
@@ -1442,7 +1454,7 @@ ext4_ext_put_gap_in_cache(struct inode *inode, struct ext4_ext_path *path, | |||
1442 | ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP); | 1454 | ext4_ext_put_in_cache(inode, lblock, len, 0, EXT4_EXT_CACHE_GAP); |
1443 | } | 1455 | } |
1444 | 1456 | ||
1445 | static inline int | 1457 | static int |
1446 | ext4_ext_in_cache(struct inode *inode, unsigned long block, | 1458 | ext4_ext_in_cache(struct inode *inode, unsigned long block, |
1447 | struct ext4_extent *ex) | 1459 | struct ext4_extent *ex) |
1448 | { | 1460 | { |
@@ -1489,10 +1501,12 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | |||
1489 | path--; | 1501 | path--; |
1490 | leaf = idx_pblock(path->p_idx); | 1502 | leaf = idx_pblock(path->p_idx); |
1491 | BUG_ON(path->p_hdr->eh_entries == 0); | 1503 | BUG_ON(path->p_hdr->eh_entries == 0); |
1492 | if ((err = ext4_ext_get_access(handle, inode, path))) | 1504 | err = ext4_ext_get_access(handle, inode, path); |
1505 | if (err) | ||
1493 | return err; | 1506 | return err; |
1494 | path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1); | 1507 | path->p_hdr->eh_entries = cpu_to_le16(le16_to_cpu(path->p_hdr->eh_entries)-1); |
1495 | if ((err = ext4_ext_dirty(handle, inode, path))) | 1508 | err = ext4_ext_dirty(handle, inode, path); |
1509 | if (err) | ||
1496 | return err; | 1510 | return err; |
1497 | ext_debug("index is empty, remove it, free block %llu\n", leaf); | 1511 | ext_debug("index is empty, remove it, free block %llu\n", leaf); |
1498 | bh = sb_find_get_block(inode->i_sb, leaf); | 1512 | bh = sb_find_get_block(inode->i_sb, leaf); |
@@ -1509,7 +1523,7 @@ int ext4_ext_rm_idx(handle_t *handle, struct inode *inode, | |||
1509 | * the caller should calculate credits under truncate_mutex and | 1523 | * the caller should calculate credits under truncate_mutex and |
1510 | * pass the actual path. | 1524 | * pass the actual path. |
1511 | */ | 1525 | */ |
1512 | int inline ext4_ext_calc_credits_for_insert(struct inode *inode, | 1526 | int ext4_ext_calc_credits_for_insert(struct inode *inode, |
1513 | struct ext4_ext_path *path) | 1527 | struct ext4_ext_path *path) |
1514 | { | 1528 | { |
1515 | int depth, needed; | 1529 | int depth, needed; |
@@ -1534,16 +1548,17 @@ int inline ext4_ext_calc_credits_for_insert(struct inode *inode, | |||
1534 | 1548 | ||
1535 | /* | 1549 | /* |
1536 | * tree can be full, so it would need to grow in depth: | 1550 | * tree can be full, so it would need to grow in depth: |
1537 | * allocation + old root + new root | 1551 | * we need one credit to modify old root, credits for |
1552 | * new root will be added in split accounting | ||
1538 | */ | 1553 | */ |
1539 | needed += 2 + 1 + 1; | 1554 | needed += 1; |
1540 | 1555 | ||
1541 | /* | 1556 | /* |
1542 | * Index split can happen, we would need: | 1557 | * Index split can happen, we would need: |
1543 | * allocate intermediate indexes (bitmap + group) | 1558 | * allocate intermediate indexes (bitmap + group) |
1544 | * + change two blocks at each level, but root (already included) | 1559 | * + change two blocks at each level, but root (already included) |
1545 | */ | 1560 | */ |
1546 | needed = (depth * 2) + (depth * 2); | 1561 | needed += (depth * 2) + (depth * 2); |
1547 | 1562 | ||
1548 | /* any allocation modifies superblock */ | 1563 | /* any allocation modifies superblock */ |
1549 | needed += 1; | 1564 | needed += 1; |
@@ -1718,7 +1733,7 @@ out: | |||
1718 | * ext4_ext_more_to_rm: | 1733 | * ext4_ext_more_to_rm: |
1719 | * returns 1 if current index has to be freed (even partial) | 1734 | * returns 1 if current index has to be freed (even partial) |
1720 | */ | 1735 | */ |
1721 | static int inline | 1736 | static int |
1722 | ext4_ext_more_to_rm(struct ext4_ext_path *path) | 1737 | ext4_ext_more_to_rm(struct ext4_ext_path *path) |
1723 | { | 1738 | { |
1724 | BUG_ON(path->p_idx == NULL); | 1739 | BUG_ON(path->p_idx == NULL); |
@@ -1756,12 +1771,11 @@ int ext4_ext_remove_space(struct inode *inode, unsigned long start) | |||
1756 | * We start scanning from right side, freeing all the blocks | 1771 | * We start scanning from right side, freeing all the blocks |
1757 | * after i_size and walking into the tree depth-wise. | 1772 | * after i_size and walking into the tree depth-wise. |
1758 | */ | 1773 | */ |
1759 | path = kmalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL); | 1774 | path = kzalloc(sizeof(struct ext4_ext_path) * (depth + 1), GFP_KERNEL); |
1760 | if (path == NULL) { | 1775 | if (path == NULL) { |
1761 | ext4_journal_stop(handle); | 1776 | ext4_journal_stop(handle); |
1762 | return -ENOMEM; | 1777 | return -ENOMEM; |
1763 | } | 1778 | } |
1764 | memset(path, 0, sizeof(struct ext4_ext_path) * (depth + 1)); | ||
1765 | path[0].p_hdr = ext_inode_hdr(inode); | 1779 | path[0].p_hdr = ext_inode_hdr(inode); |
1766 | if (ext4_ext_check_header(__FUNCTION__, inode, path[0].p_hdr)) { | 1780 | if (ext4_ext_check_header(__FUNCTION__, inode, path[0].p_hdr)) { |
1767 | err = -EIO; | 1781 | err = -EIO; |
@@ -1932,7 +1946,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
1932 | mutex_lock(&EXT4_I(inode)->truncate_mutex); | 1946 | mutex_lock(&EXT4_I(inode)->truncate_mutex); |
1933 | 1947 | ||
1934 | /* check in cache */ | 1948 | /* check in cache */ |
1935 | if ((goal = ext4_ext_in_cache(inode, iblock, &newex))) { | 1949 | goal = ext4_ext_in_cache(inode, iblock, &newex); |
1950 | if (goal) { | ||
1936 | if (goal == EXT4_EXT_CACHE_GAP) { | 1951 | if (goal == EXT4_EXT_CACHE_GAP) { |
1937 | if (!create) { | 1952 | if (!create) { |
1938 | /* block isn't allocated yet and | 1953 | /* block isn't allocated yet and |
@@ -1971,7 +1986,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | |||
1971 | */ | 1986 | */ |
1972 | BUG_ON(path[depth].p_ext == NULL && depth != 0); | 1987 | BUG_ON(path[depth].p_ext == NULL && depth != 0); |
1973 | 1988 | ||
1974 | if ((ex = path[depth].p_ext)) { | 1989 | ex = path[depth].p_ext; |
1990 | if (ex) { | ||
1975 | unsigned long ee_block = le32_to_cpu(ex->ee_block); | 1991 | unsigned long ee_block = le32_to_cpu(ex->ee_block); |
1976 | ext4_fsblk_t ee_start = ext_pblock(ex); | 1992 | ext4_fsblk_t ee_start = ext_pblock(ex); |
1977 | unsigned short ee_len = le16_to_cpu(ex->ee_len); | 1993 | unsigned short ee_len = le16_to_cpu(ex->ee_len); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0a60ec5a16db..1d85d4ec9598 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1147,37 +1147,102 @@ static int do_journal_get_write_access(handle_t *handle, | |||
1147 | return ext4_journal_get_write_access(handle, bh); | 1147 | return ext4_journal_get_write_access(handle, bh); |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | /* | ||
1151 | * The idea of this helper function is following: | ||
1152 | * if prepare_write has allocated some blocks, but not all of them, the | ||
1153 | * transaction must include the content of the newly allocated blocks. | ||
1154 | * This content is expected to be set to zeroes by block_prepare_write(). | ||
1155 | * 2006/10/14 SAW | ||
1156 | */ | ||
1157 | static int ext4_prepare_failure(struct file *file, struct page *page, | ||
1158 | unsigned from, unsigned to) | ||
1159 | { | ||
1160 | struct address_space *mapping; | ||
1161 | struct buffer_head *bh, *head, *next; | ||
1162 | unsigned block_start, block_end; | ||
1163 | unsigned blocksize; | ||
1164 | int ret; | ||
1165 | handle_t *handle = ext4_journal_current_handle(); | ||
1166 | |||
1167 | mapping = page->mapping; | ||
1168 | if (ext4_should_writeback_data(mapping->host)) { | ||
1169 | /* optimization: no constraints about data */ | ||
1170 | skip: | ||
1171 | return ext4_journal_stop(handle); | ||
1172 | } | ||
1173 | |||
1174 | head = page_buffers(page); | ||
1175 | blocksize = head->b_size; | ||
1176 | for ( bh = head, block_start = 0; | ||
1177 | bh != head || !block_start; | ||
1178 | block_start = block_end, bh = next) | ||
1179 | { | ||
1180 | next = bh->b_this_page; | ||
1181 | block_end = block_start + blocksize; | ||
1182 | if (block_end <= from) | ||
1183 | continue; | ||
1184 | if (block_start >= to) { | ||
1185 | block_start = to; | ||
1186 | break; | ||
1187 | } | ||
1188 | if (!buffer_mapped(bh)) | ||
1189 | /* prepare_write failed on this bh */ | ||
1190 | break; | ||
1191 | if (ext4_should_journal_data(mapping->host)) { | ||
1192 | ret = do_journal_get_write_access(handle, bh); | ||
1193 | if (ret) { | ||
1194 | ext4_journal_stop(handle); | ||
1195 | return ret; | ||
1196 | } | ||
1197 | } | ||
1198 | /* | ||
1199 | * block_start here becomes the first block where the current iteration | ||
1200 | * of prepare_write failed. | ||
1201 | */ | ||
1202 | } | ||
1203 | if (block_start <= from) | ||
1204 | goto skip; | ||
1205 | |||
1206 | /* commit allocated and zeroed buffers */ | ||
1207 | return mapping->a_ops->commit_write(file, page, from, block_start); | ||
1208 | } | ||
1209 | |||
1150 | static int ext4_prepare_write(struct file *file, struct page *page, | 1210 | static int ext4_prepare_write(struct file *file, struct page *page, |
1151 | unsigned from, unsigned to) | 1211 | unsigned from, unsigned to) |
1152 | { | 1212 | { |
1153 | struct inode *inode = page->mapping->host; | 1213 | struct inode *inode = page->mapping->host; |
1154 | int ret, needed_blocks = ext4_writepage_trans_blocks(inode); | 1214 | int ret, ret2; |
1215 | int needed_blocks = ext4_writepage_trans_blocks(inode); | ||
1155 | handle_t *handle; | 1216 | handle_t *handle; |
1156 | int retries = 0; | 1217 | int retries = 0; |
1157 | 1218 | ||
1158 | retry: | 1219 | retry: |
1159 | handle = ext4_journal_start(inode, needed_blocks); | 1220 | handle = ext4_journal_start(inode, needed_blocks); |
1160 | if (IS_ERR(handle)) { | 1221 | if (IS_ERR(handle)) |
1161 | ret = PTR_ERR(handle); | 1222 | return PTR_ERR(handle); |
1162 | goto out; | ||
1163 | } | ||
1164 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) | 1223 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) |
1165 | ret = nobh_prepare_write(page, from, to, ext4_get_block); | 1224 | ret = nobh_prepare_write(page, from, to, ext4_get_block); |
1166 | else | 1225 | else |
1167 | ret = block_prepare_write(page, from, to, ext4_get_block); | 1226 | ret = block_prepare_write(page, from, to, ext4_get_block); |
1168 | if (ret) | 1227 | if (ret) |
1169 | goto prepare_write_failed; | 1228 | goto failure; |
1170 | 1229 | ||
1171 | if (ext4_should_journal_data(inode)) { | 1230 | if (ext4_should_journal_data(inode)) { |
1172 | ret = walk_page_buffers(handle, page_buffers(page), | 1231 | ret = walk_page_buffers(handle, page_buffers(page), |
1173 | from, to, NULL, do_journal_get_write_access); | 1232 | from, to, NULL, do_journal_get_write_access); |
1233 | if (ret) | ||
1234 | /* fatal error, just put the handle and return */ | ||
1235 | journal_stop(handle); | ||
1174 | } | 1236 | } |
1175 | prepare_write_failed: | 1237 | return ret; |
1176 | if (ret) | 1238 | |
1177 | ext4_journal_stop(handle); | 1239 | failure: |
1240 | ret2 = ext4_prepare_failure(file, page, from, to); | ||
1241 | if (ret2 < 0) | ||
1242 | return ret2; | ||
1178 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 1243 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
1179 | goto retry; | 1244 | goto retry; |
1180 | out: | 1245 | /* retry number exceeded, or other error like -EDQUOT */ |
1181 | return ret; | 1246 | return ret; |
1182 | } | 1247 | } |
1183 | 1248 | ||
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 8b1bd03d20f5..859990eac504 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -552,6 +552,15 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
552 | dir->i_sb->s_blocksize - | 552 | dir->i_sb->s_blocksize - |
553 | EXT4_DIR_REC_LEN(0)); | 553 | EXT4_DIR_REC_LEN(0)); |
554 | for (; de < top; de = ext4_next_entry(de)) { | 554 | for (; de < top; de = ext4_next_entry(de)) { |
555 | if (!ext4_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, | ||
556 | (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) | ||
557 | +((char *)de - bh->b_data))) { | ||
558 | /* On error, skip the f_pos to the next block. */ | ||
559 | dir_file->f_pos = (dir_file->f_pos | | ||
560 | (dir->i_sb->s_blocksize - 1)) + 1; | ||
561 | brelse (bh); | ||
562 | return count; | ||
563 | } | ||
555 | ext4fs_dirhash(de->name, de->name_len, hinfo); | 564 | ext4fs_dirhash(de->name, de->name_len, hinfo); |
556 | if ((hinfo->hash < start_hash) || | 565 | if ((hinfo->hash < start_hash) || |
557 | ((hinfo->hash == start_hash) && | 566 | ((hinfo->hash == start_hash) && |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index b4b022aa2bc2..486a641ca71b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -486,7 +486,7 @@ static void ext4_put_super (struct super_block * sb) | |||
486 | return; | 486 | return; |
487 | } | 487 | } |
488 | 488 | ||
489 | static kmem_cache_t *ext4_inode_cachep; | 489 | static struct kmem_cache *ext4_inode_cachep; |
490 | 490 | ||
491 | /* | 491 | /* |
492 | * Called inside transaction, so use GFP_NOFS | 492 | * Called inside transaction, so use GFP_NOFS |
@@ -495,7 +495,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
495 | { | 495 | { |
496 | struct ext4_inode_info *ei; | 496 | struct ext4_inode_info *ei; |
497 | 497 | ||
498 | ei = kmem_cache_alloc(ext4_inode_cachep, SLAB_NOFS); | 498 | ei = kmem_cache_alloc(ext4_inode_cachep, GFP_NOFS); |
499 | if (!ei) | 499 | if (!ei) |
500 | return NULL; | 500 | return NULL; |
501 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL | 501 | #ifdef CONFIG_EXT4DEV_FS_POSIX_ACL |
@@ -513,7 +513,7 @@ static void ext4_destroy_inode(struct inode *inode) | |||
513 | kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); | 513 | kmem_cache_free(ext4_inode_cachep, EXT4_I(inode)); |
514 | } | 514 | } |
515 | 515 | ||
516 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 516 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
517 | { | 517 | { |
518 | struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; | 518 | struct ext4_inode_info *ei = (struct ext4_inode_info *) foo; |
519 | 519 | ||
@@ -1321,6 +1321,12 @@ static void ext4_orphan_cleanup (struct super_block * sb, | |||
1321 | return; | 1321 | return; |
1322 | } | 1322 | } |
1323 | 1323 | ||
1324 | if (bdev_read_only(sb->s_bdev)) { | ||
1325 | printk(KERN_ERR "EXT4-fs: write access " | ||
1326 | "unavailable, skipping orphan cleanup.\n"); | ||
1327 | return; | ||
1328 | } | ||
1329 | |||
1324 | if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) { | 1330 | if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) { |
1325 | if (es->s_last_orphan) | 1331 | if (es->s_last_orphan) |
1326 | jbd_debug(1, "Errors on filesystem, " | 1332 | jbd_debug(1, "Errors on filesystem, " |
@@ -2460,6 +2466,7 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2460 | struct ext4_super_block *es = sbi->s_es; | 2466 | struct ext4_super_block *es = sbi->s_es; |
2461 | ext4_fsblk_t overhead; | 2467 | ext4_fsblk_t overhead; |
2462 | int i; | 2468 | int i; |
2469 | u64 fsid; | ||
2463 | 2470 | ||
2464 | if (test_opt (sb, MINIX_DF)) | 2471 | if (test_opt (sb, MINIX_DF)) |
2465 | overhead = 0; | 2472 | overhead = 0; |
@@ -2506,6 +2513,10 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2506 | buf->f_files = le32_to_cpu(es->s_inodes_count); | 2513 | buf->f_files = le32_to_cpu(es->s_inodes_count); |
2507 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); | 2514 | buf->f_ffree = percpu_counter_sum(&sbi->s_freeinodes_counter); |
2508 | buf->f_namelen = EXT4_NAME_LEN; | 2515 | buf->f_namelen = EXT4_NAME_LEN; |
2516 | fsid = le64_to_cpup((void *)es->s_uuid) ^ | ||
2517 | le64_to_cpup((void *)es->s_uuid + sizeof(u64)); | ||
2518 | buf->f_fsid.val[0] = fsid & 0xFFFFFFFFUL; | ||
2519 | buf->f_fsid.val[1] = (fsid >> 32) & 0xFFFFFFFFUL; | ||
2509 | return 0; | 2520 | return 0; |
2510 | } | 2521 | } |
2511 | 2522 | ||
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 63233cd946a7..dc969c357aa1 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -459,14 +459,11 @@ static void ext4_xattr_update_super_block(handle_t *handle, | |||
459 | if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR)) | 459 | if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR)) |
460 | return; | 460 | return; |
461 | 461 | ||
462 | lock_super(sb); | ||
463 | if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { | 462 | if (ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh) == 0) { |
464 | EXT4_SB(sb)->s_es->s_feature_compat |= | 463 | EXT4_SET_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_EXT_ATTR); |
465 | cpu_to_le32(EXT4_FEATURE_COMPAT_EXT_ATTR); | ||
466 | sb->s_dirt = 1; | 464 | sb->s_dirt = 1; |
467 | ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); | 465 | ext4_journal_dirty_metadata(handle, EXT4_SB(sb)->s_sbh); |
468 | } | 466 | } |
469 | unlock_super(sb); | ||
470 | } | 467 | } |
471 | 468 | ||
472 | /* | 469 | /* |
diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 82cc4f59e3ba..05c2941c74f2 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c | |||
@@ -34,9 +34,9 @@ static inline int fat_max_cache(struct inode *inode) | |||
34 | return FAT_MAX_CACHE; | 34 | return FAT_MAX_CACHE; |
35 | } | 35 | } |
36 | 36 | ||
37 | static kmem_cache_t *fat_cache_cachep; | 37 | static struct kmem_cache *fat_cache_cachep; |
38 | 38 | ||
39 | static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 39 | static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
40 | { | 40 | { |
41 | struct fat_cache *cache = (struct fat_cache *)foo; | 41 | struct fat_cache *cache = (struct fat_cache *)foo; |
42 | 42 | ||
@@ -63,7 +63,7 @@ void fat_cache_destroy(void) | |||
63 | 63 | ||
64 | static inline struct fat_cache *fat_cache_alloc(struct inode *inode) | 64 | static inline struct fat_cache *fat_cache_alloc(struct inode *inode) |
65 | { | 65 | { |
66 | return kmem_cache_alloc(fat_cache_cachep, SLAB_KERNEL); | 66 | return kmem_cache_alloc(fat_cache_cachep, GFP_KERNEL); |
67 | } | 67 | } |
68 | 68 | ||
69 | static inline void fat_cache_free(struct fat_cache *cache) | 69 | static inline void fat_cache_free(struct fat_cache *cache) |
diff --git a/fs/fat/file.c b/fs/fat/file.c index 8337451e7897..0aa813d944a6 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -303,7 +303,17 @@ void fat_truncate(struct inode *inode) | |||
303 | fat_flush_inodes(inode->i_sb, inode, NULL); | 303 | fat_flush_inodes(inode->i_sb, inode, NULL); |
304 | } | 304 | } |
305 | 305 | ||
306 | int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | ||
307 | { | ||
308 | struct inode *inode = dentry->d_inode; | ||
309 | generic_fillattr(inode, stat); | ||
310 | stat->blksize = MSDOS_SB(inode->i_sb)->cluster_size; | ||
311 | return 0; | ||
312 | } | ||
313 | EXPORT_SYMBOL_GPL(fat_getattr); | ||
314 | |||
306 | struct inode_operations fat_file_inode_operations = { | 315 | struct inode_operations fat_file_inode_operations = { |
307 | .truncate = fat_truncate, | 316 | .truncate = fat_truncate, |
308 | .setattr = fat_notify_change, | 317 | .setattr = fat_notify_change, |
318 | .getattr = fat_getattr, | ||
309 | }; | 319 | }; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 78945b53b0f8..a9e4688582a2 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -477,12 +477,12 @@ static void fat_put_super(struct super_block *sb) | |||
477 | kfree(sbi); | 477 | kfree(sbi); |
478 | } | 478 | } |
479 | 479 | ||
480 | static kmem_cache_t *fat_inode_cachep; | 480 | static struct kmem_cache *fat_inode_cachep; |
481 | 481 | ||
482 | static struct inode *fat_alloc_inode(struct super_block *sb) | 482 | static struct inode *fat_alloc_inode(struct super_block *sb) |
483 | { | 483 | { |
484 | struct msdos_inode_info *ei; | 484 | struct msdos_inode_info *ei; |
485 | ei = kmem_cache_alloc(fat_inode_cachep, SLAB_KERNEL); | 485 | ei = kmem_cache_alloc(fat_inode_cachep, GFP_KERNEL); |
486 | if (!ei) | 486 | if (!ei) |
487 | return NULL; | 487 | return NULL; |
488 | return &ei->vfs_inode; | 488 | return &ei->vfs_inode; |
@@ -493,7 +493,7 @@ static void fat_destroy_inode(struct inode *inode) | |||
493 | kmem_cache_free(fat_inode_cachep, MSDOS_I(inode)); | 493 | kmem_cache_free(fat_inode_cachep, MSDOS_I(inode)); |
494 | } | 494 | } |
495 | 495 | ||
496 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 496 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
497 | { | 497 | { |
498 | struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; | 498 | struct msdos_inode_info *ei = (struct msdos_inode_info *)foo; |
499 | 499 | ||
diff --git a/fs/fcntl.c b/fs/fcntl.c index e4f26165f12a..4740d35e52cd 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -553,7 +553,7 @@ int send_sigurg(struct fown_struct *fown) | |||
553 | } | 553 | } |
554 | 554 | ||
555 | static DEFINE_RWLOCK(fasync_lock); | 555 | static DEFINE_RWLOCK(fasync_lock); |
556 | static kmem_cache_t *fasync_cache __read_mostly; | 556 | static struct kmem_cache *fasync_cache __read_mostly; |
557 | 557 | ||
558 | /* | 558 | /* |
559 | * fasync_helper() is used by some character device drivers (mainly mice) | 559 | * fasync_helper() is used by some character device drivers (mainly mice) |
@@ -567,7 +567,7 @@ int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fap | |||
567 | int result = 0; | 567 | int result = 0; |
568 | 568 | ||
569 | if (on) { | 569 | if (on) { |
570 | new = kmem_cache_alloc(fasync_cache, SLAB_KERNEL); | 570 | new = kmem_cache_alloc(fasync_cache, GFP_KERNEL); |
571 | if (!new) | 571 | if (!new) |
572 | return -ENOMEM; | 572 | return -ENOMEM; |
573 | } | 573 | } |
@@ -21,7 +21,6 @@ | |||
21 | struct fdtable_defer { | 21 | struct fdtable_defer { |
22 | spinlock_t lock; | 22 | spinlock_t lock; |
23 | struct work_struct wq; | 23 | struct work_struct wq; |
24 | struct timer_list timer; | ||
25 | struct fdtable *next; | 24 | struct fdtable *next; |
26 | }; | 25 | }; |
27 | 26 | ||
@@ -75,24 +74,10 @@ static void __free_fdtable(struct fdtable *fdt) | |||
75 | kfree(fdt); | 74 | kfree(fdt); |
76 | } | 75 | } |
77 | 76 | ||
78 | static void fdtable_timer(unsigned long data) | 77 | static void free_fdtable_work(struct work_struct *work) |
79 | { | ||
80 | struct fdtable_defer *fddef = (struct fdtable_defer *)data; | ||
81 | |||
82 | spin_lock(&fddef->lock); | ||
83 | /* | ||
84 | * If someone already emptied the queue return. | ||
85 | */ | ||
86 | if (!fddef->next) | ||
87 | goto out; | ||
88 | if (!schedule_work(&fddef->wq)) | ||
89 | mod_timer(&fddef->timer, 5); | ||
90 | out: | ||
91 | spin_unlock(&fddef->lock); | ||
92 | } | ||
93 | |||
94 | static void free_fdtable_work(struct fdtable_defer *f) | ||
95 | { | 78 | { |
79 | struct fdtable_defer *f = | ||
80 | container_of(work, struct fdtable_defer, wq); | ||
96 | struct fdtable *fdt; | 81 | struct fdtable *fdt; |
97 | 82 | ||
98 | spin_lock_bh(&f->lock); | 83 | spin_lock_bh(&f->lock); |
@@ -142,13 +127,8 @@ static void free_fdtable_rcu(struct rcu_head *rcu) | |||
142 | spin_lock(&fddef->lock); | 127 | spin_lock(&fddef->lock); |
143 | fdt->next = fddef->next; | 128 | fdt->next = fddef->next; |
144 | fddef->next = fdt; | 129 | fddef->next = fdt; |
145 | /* | 130 | /* vmallocs are handled from the workqueue context */ |
146 | * vmallocs are handled from the workqueue context. | 131 | schedule_work(&fddef->wq); |
147 | * If the per-cpu workqueue is running, then we | ||
148 | * defer work scheduling through a timer. | ||
149 | */ | ||
150 | if (!schedule_work(&fddef->wq)) | ||
151 | mod_timer(&fddef->timer, 5); | ||
152 | spin_unlock(&fddef->lock); | 132 | spin_unlock(&fddef->lock); |
153 | put_cpu_var(fdtable_defer_list); | 133 | put_cpu_var(fdtable_defer_list); |
154 | } | 134 | } |
@@ -351,10 +331,7 @@ static void __devinit fdtable_defer_list_init(int cpu) | |||
351 | { | 331 | { |
352 | struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); | 332 | struct fdtable_defer *fddef = &per_cpu(fdtable_defer_list, cpu); |
353 | spin_lock_init(&fddef->lock); | 333 | spin_lock_init(&fddef->lock); |
354 | INIT_WORK(&fddef->wq, (void (*)(void *))free_fdtable_work, fddef); | 334 | INIT_WORK(&fddef->wq, free_fdtable_work); |
355 | init_timer(&fddef->timer); | ||
356 | fddef->timer.data = (unsigned long)fddef; | ||
357 | fddef->timer.function = fdtable_timer; | ||
358 | fddef->next = NULL; | 335 | fddef->next = NULL; |
359 | } | 336 | } |
360 | 337 | ||
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index 4786d51ad3bd..0b7ae897cb78 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
@@ -46,7 +46,7 @@ extern const struct address_space_operations vxfs_immed_aops; | |||
46 | 46 | ||
47 | extern struct inode_operations vxfs_immed_symlink_iops; | 47 | extern struct inode_operations vxfs_immed_symlink_iops; |
48 | 48 | ||
49 | kmem_cache_t *vxfs_inode_cachep; | 49 | struct kmem_cache *vxfs_inode_cachep; |
50 | 50 | ||
51 | 51 | ||
52 | #ifdef DIAGNOSTIC | 52 | #ifdef DIAGNOSTIC |
@@ -103,7 +103,7 @@ vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) | |||
103 | struct vxfs_inode_info *vip; | 103 | struct vxfs_inode_info *vip; |
104 | struct vxfs_dinode *dip; | 104 | struct vxfs_dinode *dip; |
105 | 105 | ||
106 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL))) | 106 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) |
107 | goto fail; | 107 | goto fail; |
108 | dip = (struct vxfs_dinode *)(bp->b_data + offset); | 108 | dip = (struct vxfs_dinode *)(bp->b_data + offset); |
109 | memcpy(vip, dip, sizeof(*vip)); | 109 | memcpy(vip, dip, sizeof(*vip)); |
@@ -145,7 +145,7 @@ __vxfs_iget(ino_t ino, struct inode *ilistp) | |||
145 | struct vxfs_dinode *dip; | 145 | struct vxfs_dinode *dip; |
146 | caddr_t kaddr = (char *)page_address(pp); | 146 | caddr_t kaddr = (char *)page_address(pp); |
147 | 147 | ||
148 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL))) | 148 | if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, GFP_KERNEL))) |
149 | goto fail; | 149 | goto fail; |
150 | dip = (struct vxfs_dinode *)(kaddr + offset); | 150 | dip = (struct vxfs_dinode *)(kaddr + offset); |
151 | memcpy(vip, dip, sizeof(*vip)); | 151 | memcpy(vip, dip, sizeof(*vip)); |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 66571eafbb1e..357764d85ff1 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | MODULE_ALIAS_MISCDEV(FUSE_MINOR); | 20 | MODULE_ALIAS_MISCDEV(FUSE_MINOR); |
21 | 21 | ||
22 | static kmem_cache_t *fuse_req_cachep; | 22 | static struct kmem_cache *fuse_req_cachep; |
23 | 23 | ||
24 | static struct fuse_conn *fuse_get_conn(struct file *file) | 24 | static struct fuse_conn *fuse_get_conn(struct file *file) |
25 | { | 25 | { |
@@ -41,7 +41,7 @@ static void fuse_request_init(struct fuse_req *req) | |||
41 | 41 | ||
42 | struct fuse_req *fuse_request_alloc(void) | 42 | struct fuse_req *fuse_request_alloc(void) |
43 | { | 43 | { |
44 | struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, SLAB_KERNEL); | 44 | struct fuse_req *req = kmem_cache_alloc(fuse_req_cachep, GFP_KERNEL); |
45 | if (req) | 45 | if (req) |
46 | fuse_request_init(req); | 46 | fuse_request_init(req); |
47 | return req; | 47 | return req; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index cfc8f81e60d0..1cabdb229adb 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -138,11 +138,9 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
138 | struct fuse_entry_out outarg; | 138 | struct fuse_entry_out outarg; |
139 | struct fuse_conn *fc; | 139 | struct fuse_conn *fc; |
140 | struct fuse_req *req; | 140 | struct fuse_req *req; |
141 | struct fuse_req *forget_req; | ||
141 | struct dentry *parent; | 142 | struct dentry *parent; |
142 | 143 | ||
143 | /* Doesn't hurt to "reset" the validity timeout */ | ||
144 | fuse_invalidate_entry_cache(entry); | ||
145 | |||
146 | /* For negative dentries, always do a fresh lookup */ | 144 | /* For negative dentries, always do a fresh lookup */ |
147 | if (!inode) | 145 | if (!inode) |
148 | return 0; | 146 | return 0; |
@@ -152,25 +150,33 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) | |||
152 | if (IS_ERR(req)) | 150 | if (IS_ERR(req)) |
153 | return 0; | 151 | return 0; |
154 | 152 | ||
153 | forget_req = fuse_get_req(fc); | ||
154 | if (IS_ERR(forget_req)) { | ||
155 | fuse_put_request(fc, req); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
155 | parent = dget_parent(entry); | 159 | parent = dget_parent(entry); |
156 | fuse_lookup_init(req, parent->d_inode, entry, &outarg); | 160 | fuse_lookup_init(req, parent->d_inode, entry, &outarg); |
157 | request_send(fc, req); | 161 | request_send(fc, req); |
158 | dput(parent); | 162 | dput(parent); |
159 | err = req->out.h.error; | 163 | err = req->out.h.error; |
164 | fuse_put_request(fc, req); | ||
160 | /* Zero nodeid is same as -ENOENT */ | 165 | /* Zero nodeid is same as -ENOENT */ |
161 | if (!err && !outarg.nodeid) | 166 | if (!err && !outarg.nodeid) |
162 | err = -ENOENT; | 167 | err = -ENOENT; |
163 | if (!err) { | 168 | if (!err) { |
164 | struct fuse_inode *fi = get_fuse_inode(inode); | 169 | struct fuse_inode *fi = get_fuse_inode(inode); |
165 | if (outarg.nodeid != get_node_id(inode)) { | 170 | if (outarg.nodeid != get_node_id(inode)) { |
166 | fuse_send_forget(fc, req, outarg.nodeid, 1); | 171 | fuse_send_forget(fc, forget_req, |
172 | outarg.nodeid, 1); | ||
167 | return 0; | 173 | return 0; |
168 | } | 174 | } |
169 | spin_lock(&fc->lock); | 175 | spin_lock(&fc->lock); |
170 | fi->nlookup ++; | 176 | fi->nlookup ++; |
171 | spin_unlock(&fc->lock); | 177 | spin_unlock(&fc->lock); |
172 | } | 178 | } |
173 | fuse_put_request(fc, req); | 179 | fuse_put_request(fc, forget_req); |
174 | if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) | 180 | if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) |
175 | return 0; | 181 | return 0; |
176 | 182 | ||
@@ -221,6 +227,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
221 | struct inode *inode = NULL; | 227 | struct inode *inode = NULL; |
222 | struct fuse_conn *fc = get_fuse_conn(dir); | 228 | struct fuse_conn *fc = get_fuse_conn(dir); |
223 | struct fuse_req *req; | 229 | struct fuse_req *req; |
230 | struct fuse_req *forget_req; | ||
224 | 231 | ||
225 | if (entry->d_name.len > FUSE_NAME_MAX) | 232 | if (entry->d_name.len > FUSE_NAME_MAX) |
226 | return ERR_PTR(-ENAMETOOLONG); | 233 | return ERR_PTR(-ENAMETOOLONG); |
@@ -229,9 +236,16 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
229 | if (IS_ERR(req)) | 236 | if (IS_ERR(req)) |
230 | return ERR_PTR(PTR_ERR(req)); | 237 | return ERR_PTR(PTR_ERR(req)); |
231 | 238 | ||
239 | forget_req = fuse_get_req(fc); | ||
240 | if (IS_ERR(forget_req)) { | ||
241 | fuse_put_request(fc, req); | ||
242 | return ERR_PTR(PTR_ERR(forget_req)); | ||
243 | } | ||
244 | |||
232 | fuse_lookup_init(req, dir, entry, &outarg); | 245 | fuse_lookup_init(req, dir, entry, &outarg); |
233 | request_send(fc, req); | 246 | request_send(fc, req); |
234 | err = req->out.h.error; | 247 | err = req->out.h.error; |
248 | fuse_put_request(fc, req); | ||
235 | /* Zero nodeid is same as -ENOENT, but with valid timeout */ | 249 | /* Zero nodeid is same as -ENOENT, but with valid timeout */ |
236 | if (!err && outarg.nodeid && | 250 | if (!err && outarg.nodeid && |
237 | (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode))) | 251 | (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode))) |
@@ -240,11 +254,11 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
240 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, | 254 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, |
241 | &outarg.attr); | 255 | &outarg.attr); |
242 | if (!inode) { | 256 | if (!inode) { |
243 | fuse_send_forget(fc, req, outarg.nodeid, 1); | 257 | fuse_send_forget(fc, forget_req, outarg.nodeid, 1); |
244 | return ERR_PTR(-ENOMEM); | 258 | return ERR_PTR(-ENOMEM); |
245 | } | 259 | } |
246 | } | 260 | } |
247 | fuse_put_request(fc, req); | 261 | fuse_put_request(fc, forget_req); |
248 | if (err && err != -ENOENT) | 262 | if (err && err != -ENOENT) |
249 | return ERR_PTR(err); | 263 | return ERR_PTR(err); |
250 | 264 | ||
@@ -388,6 +402,13 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
388 | struct fuse_entry_out outarg; | 402 | struct fuse_entry_out outarg; |
389 | struct inode *inode; | 403 | struct inode *inode; |
390 | int err; | 404 | int err; |
405 | struct fuse_req *forget_req; | ||
406 | |||
407 | forget_req = fuse_get_req(fc); | ||
408 | if (IS_ERR(forget_req)) { | ||
409 | fuse_put_request(fc, req); | ||
410 | return PTR_ERR(forget_req); | ||
411 | } | ||
391 | 412 | ||
392 | req->in.h.nodeid = get_node_id(dir); | 413 | req->in.h.nodeid = get_node_id(dir); |
393 | req->out.numargs = 1; | 414 | req->out.numargs = 1; |
@@ -395,24 +416,24 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
395 | req->out.args[0].value = &outarg; | 416 | req->out.args[0].value = &outarg; |
396 | request_send(fc, req); | 417 | request_send(fc, req); |
397 | err = req->out.h.error; | 418 | err = req->out.h.error; |
398 | if (err) { | 419 | fuse_put_request(fc, req); |
399 | fuse_put_request(fc, req); | 420 | if (err) |
400 | return err; | 421 | goto out_put_forget_req; |
401 | } | 422 | |
402 | err = -EIO; | 423 | err = -EIO; |
403 | if (invalid_nodeid(outarg.nodeid)) | 424 | if (invalid_nodeid(outarg.nodeid)) |
404 | goto out_put_request; | 425 | goto out_put_forget_req; |
405 | 426 | ||
406 | if ((outarg.attr.mode ^ mode) & S_IFMT) | 427 | if ((outarg.attr.mode ^ mode) & S_IFMT) |
407 | goto out_put_request; | 428 | goto out_put_forget_req; |
408 | 429 | ||
409 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, | 430 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, |
410 | &outarg.attr); | 431 | &outarg.attr); |
411 | if (!inode) { | 432 | if (!inode) { |
412 | fuse_send_forget(fc, req, outarg.nodeid, 1); | 433 | fuse_send_forget(fc, forget_req, outarg.nodeid, 1); |
413 | return -ENOMEM; | 434 | return -ENOMEM; |
414 | } | 435 | } |
415 | fuse_put_request(fc, req); | 436 | fuse_put_request(fc, forget_req); |
416 | 437 | ||
417 | if (S_ISDIR(inode->i_mode)) { | 438 | if (S_ISDIR(inode->i_mode)) { |
418 | struct dentry *alias; | 439 | struct dentry *alias; |
@@ -434,8 +455,8 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, | |||
434 | fuse_invalidate_attr(dir); | 455 | fuse_invalidate_attr(dir); |
435 | return 0; | 456 | return 0; |
436 | 457 | ||
437 | out_put_request: | 458 | out_put_forget_req: |
438 | fuse_put_request(fc, req); | 459 | fuse_put_request(fc, forget_req); |
439 | return err; | 460 | return err; |
440 | } | 461 | } |
441 | 462 | ||
@@ -1003,6 +1024,8 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) | |||
1003 | if (attr->ia_valid & ATTR_SIZE) { | 1024 | if (attr->ia_valid & ATTR_SIZE) { |
1004 | unsigned long limit; | 1025 | unsigned long limit; |
1005 | is_truncate = 1; | 1026 | is_truncate = 1; |
1027 | if (IS_SWAPFILE(inode)) | ||
1028 | return -ETXTBSY; | ||
1006 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; | 1029 | limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; |
1007 | if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) { | 1030 | if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) { |
1008 | send_sig(SIGXFSZ, current, 0); | 1031 | send_sig(SIGXFSZ, current, 0); |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 763a50daf1c0..128f79c40803 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -754,6 +754,42 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) | |||
754 | return err; | 754 | return err; |
755 | } | 755 | } |
756 | 756 | ||
757 | static sector_t fuse_bmap(struct address_space *mapping, sector_t block) | ||
758 | { | ||
759 | struct inode *inode = mapping->host; | ||
760 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
761 | struct fuse_req *req; | ||
762 | struct fuse_bmap_in inarg; | ||
763 | struct fuse_bmap_out outarg; | ||
764 | int err; | ||
765 | |||
766 | if (!inode->i_sb->s_bdev || fc->no_bmap) | ||
767 | return 0; | ||
768 | |||
769 | req = fuse_get_req(fc); | ||
770 | if (IS_ERR(req)) | ||
771 | return 0; | ||
772 | |||
773 | memset(&inarg, 0, sizeof(inarg)); | ||
774 | inarg.block = block; | ||
775 | inarg.blocksize = inode->i_sb->s_blocksize; | ||
776 | req->in.h.opcode = FUSE_BMAP; | ||
777 | req->in.h.nodeid = get_node_id(inode); | ||
778 | req->in.numargs = 1; | ||
779 | req->in.args[0].size = sizeof(inarg); | ||
780 | req->in.args[0].value = &inarg; | ||
781 | req->out.numargs = 1; | ||
782 | req->out.args[0].size = sizeof(outarg); | ||
783 | req->out.args[0].value = &outarg; | ||
784 | request_send(fc, req); | ||
785 | err = req->out.h.error; | ||
786 | fuse_put_request(fc, req); | ||
787 | if (err == -ENOSYS) | ||
788 | fc->no_bmap = 1; | ||
789 | |||
790 | return err ? 0 : outarg.block; | ||
791 | } | ||
792 | |||
757 | static const struct file_operations fuse_file_operations = { | 793 | static const struct file_operations fuse_file_operations = { |
758 | .llseek = generic_file_llseek, | 794 | .llseek = generic_file_llseek, |
759 | .read = do_sync_read, | 795 | .read = do_sync_read, |
@@ -787,6 +823,7 @@ static const struct address_space_operations fuse_file_aops = { | |||
787 | .commit_write = fuse_commit_write, | 823 | .commit_write = fuse_commit_write, |
788 | .readpages = fuse_readpages, | 824 | .readpages = fuse_readpages, |
789 | .set_page_dirty = fuse_set_page_dirty, | 825 | .set_page_dirty = fuse_set_page_dirty, |
826 | .bmap = fuse_bmap, | ||
790 | }; | 827 | }; |
791 | 828 | ||
792 | void fuse_init_file_inode(struct inode *inode) | 829 | void fuse_init_file_inode(struct inode *inode) |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 91edb8932d90..b98b20de7405 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -298,6 +298,9 @@ struct fuse_conn { | |||
298 | reply, before any other request, and never cleared */ | 298 | reply, before any other request, and never cleared */ |
299 | unsigned conn_error : 1; | 299 | unsigned conn_error : 1; |
300 | 300 | ||
301 | /** Connection successful. Only set in INIT */ | ||
302 | unsigned conn_init : 1; | ||
303 | |||
301 | /** Do readpages asynchronously? Only set in INIT */ | 304 | /** Do readpages asynchronously? Only set in INIT */ |
302 | unsigned async_read : 1; | 305 | unsigned async_read : 1; |
303 | 306 | ||
@@ -339,6 +342,9 @@ struct fuse_conn { | |||
339 | /** Is interrupt not implemented by fs? */ | 342 | /** Is interrupt not implemented by fs? */ |
340 | unsigned no_interrupt : 1; | 343 | unsigned no_interrupt : 1; |
341 | 344 | ||
345 | /** Is bmap not implemented by fs? */ | ||
346 | unsigned no_bmap : 1; | ||
347 | |||
342 | /** The number of requests waiting for completion */ | 348 | /** The number of requests waiting for completion */ |
343 | atomic_t num_waiting; | 349 | atomic_t num_waiting; |
344 | 350 | ||
@@ -365,6 +371,9 @@ struct fuse_conn { | |||
365 | 371 | ||
366 | /** Key for lock owner ID scrambling */ | 372 | /** Key for lock owner ID scrambling */ |
367 | u32 scramble_key[4]; | 373 | u32 scramble_key[4]; |
374 | |||
375 | /** Reserved request for the DESTROY message */ | ||
376 | struct fuse_req *destroy_req; | ||
368 | }; | 377 | }; |
369 | 378 | ||
370 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) | 379 | static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index fc4203570370..12450d2b320e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -22,7 +22,7 @@ MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>"); | |||
22 | MODULE_DESCRIPTION("Filesystem in Userspace"); | 22 | MODULE_DESCRIPTION("Filesystem in Userspace"); |
23 | MODULE_LICENSE("GPL"); | 23 | MODULE_LICENSE("GPL"); |
24 | 24 | ||
25 | static kmem_cache_t *fuse_inode_cachep; | 25 | static struct kmem_cache *fuse_inode_cachep; |
26 | struct list_head fuse_conn_list; | 26 | struct list_head fuse_conn_list; |
27 | DEFINE_MUTEX(fuse_mutex); | 27 | DEFINE_MUTEX(fuse_mutex); |
28 | 28 | ||
@@ -39,6 +39,7 @@ struct fuse_mount_data { | |||
39 | unsigned group_id_present : 1; | 39 | unsigned group_id_present : 1; |
40 | unsigned flags; | 40 | unsigned flags; |
41 | unsigned max_read; | 41 | unsigned max_read; |
42 | unsigned blksize; | ||
42 | }; | 43 | }; |
43 | 44 | ||
44 | static struct inode *fuse_alloc_inode(struct super_block *sb) | 45 | static struct inode *fuse_alloc_inode(struct super_block *sb) |
@@ -46,7 +47,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) | |||
46 | struct inode *inode; | 47 | struct inode *inode; |
47 | struct fuse_inode *fi; | 48 | struct fuse_inode *fi; |
48 | 49 | ||
49 | inode = kmem_cache_alloc(fuse_inode_cachep, SLAB_KERNEL); | 50 | inode = kmem_cache_alloc(fuse_inode_cachep, GFP_KERNEL); |
50 | if (!inode) | 51 | if (!inode) |
51 | return NULL; | 52 | return NULL; |
52 | 53 | ||
@@ -205,10 +206,23 @@ static void fuse_umount_begin(struct vfsmount *vfsmnt, int flags) | |||
205 | fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb)); | 206 | fuse_abort_conn(get_fuse_conn_super(vfsmnt->mnt_sb)); |
206 | } | 207 | } |
207 | 208 | ||
209 | static void fuse_send_destroy(struct fuse_conn *fc) | ||
210 | { | ||
211 | struct fuse_req *req = fc->destroy_req; | ||
212 | if (req && fc->conn_init) { | ||
213 | fc->destroy_req = NULL; | ||
214 | req->in.h.opcode = FUSE_DESTROY; | ||
215 | req->force = 1; | ||
216 | request_send(fc, req); | ||
217 | fuse_put_request(fc, req); | ||
218 | } | ||
219 | } | ||
220 | |||
208 | static void fuse_put_super(struct super_block *sb) | 221 | static void fuse_put_super(struct super_block *sb) |
209 | { | 222 | { |
210 | struct fuse_conn *fc = get_fuse_conn_super(sb); | 223 | struct fuse_conn *fc = get_fuse_conn_super(sb); |
211 | 224 | ||
225 | fuse_send_destroy(fc); | ||
212 | spin_lock(&fc->lock); | 226 | spin_lock(&fc->lock); |
213 | fc->connected = 0; | 227 | fc->connected = 0; |
214 | fc->blocked = 0; | 228 | fc->blocked = 0; |
@@ -274,6 +288,7 @@ enum { | |||
274 | OPT_DEFAULT_PERMISSIONS, | 288 | OPT_DEFAULT_PERMISSIONS, |
275 | OPT_ALLOW_OTHER, | 289 | OPT_ALLOW_OTHER, |
276 | OPT_MAX_READ, | 290 | OPT_MAX_READ, |
291 | OPT_BLKSIZE, | ||
277 | OPT_ERR | 292 | OPT_ERR |
278 | }; | 293 | }; |
279 | 294 | ||
@@ -285,14 +300,16 @@ static match_table_t tokens = { | |||
285 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, | 300 | {OPT_DEFAULT_PERMISSIONS, "default_permissions"}, |
286 | {OPT_ALLOW_OTHER, "allow_other"}, | 301 | {OPT_ALLOW_OTHER, "allow_other"}, |
287 | {OPT_MAX_READ, "max_read=%u"}, | 302 | {OPT_MAX_READ, "max_read=%u"}, |
303 | {OPT_BLKSIZE, "blksize=%u"}, | ||
288 | {OPT_ERR, NULL} | 304 | {OPT_ERR, NULL} |
289 | }; | 305 | }; |
290 | 306 | ||
291 | static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) | 307 | static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) |
292 | { | 308 | { |
293 | char *p; | 309 | char *p; |
294 | memset(d, 0, sizeof(struct fuse_mount_data)); | 310 | memset(d, 0, sizeof(struct fuse_mount_data)); |
295 | d->max_read = ~0; | 311 | d->max_read = ~0; |
312 | d->blksize = 512; | ||
296 | 313 | ||
297 | while ((p = strsep(&opt, ",")) != NULL) { | 314 | while ((p = strsep(&opt, ",")) != NULL) { |
298 | int token; | 315 | int token; |
@@ -345,6 +362,12 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d) | |||
345 | d->max_read = value; | 362 | d->max_read = value; |
346 | break; | 363 | break; |
347 | 364 | ||
365 | case OPT_BLKSIZE: | ||
366 | if (!is_bdev || match_int(&args[0], &value)) | ||
367 | return 0; | ||
368 | d->blksize = value; | ||
369 | break; | ||
370 | |||
348 | default: | 371 | default: |
349 | return 0; | 372 | return 0; |
350 | } | 373 | } |
@@ -400,6 +423,8 @@ static struct fuse_conn *new_conn(void) | |||
400 | void fuse_conn_put(struct fuse_conn *fc) | 423 | void fuse_conn_put(struct fuse_conn *fc) |
401 | { | 424 | { |
402 | if (atomic_dec_and_test(&fc->count)) { | 425 | if (atomic_dec_and_test(&fc->count)) { |
426 | if (fc->destroy_req) | ||
427 | fuse_request_free(fc->destroy_req); | ||
403 | mutex_destroy(&fc->inst_mutex); | 428 | mutex_destroy(&fc->inst_mutex); |
404 | kfree(fc); | 429 | kfree(fc); |
405 | } | 430 | } |
@@ -456,6 +481,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
456 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); | 481 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); |
457 | fc->minor = arg->minor; | 482 | fc->minor = arg->minor; |
458 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; | 483 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; |
484 | fc->conn_init = 1; | ||
459 | } | 485 | } |
460 | fuse_put_request(fc, req); | 486 | fuse_put_request(fc, req); |
461 | fc->blocked = 0; | 487 | fc->blocked = 0; |
@@ -500,15 +526,23 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
500 | struct dentry *root_dentry; | 526 | struct dentry *root_dentry; |
501 | struct fuse_req *init_req; | 527 | struct fuse_req *init_req; |
502 | int err; | 528 | int err; |
529 | int is_bdev = sb->s_bdev != NULL; | ||
503 | 530 | ||
504 | if (sb->s_flags & MS_MANDLOCK) | 531 | if (sb->s_flags & MS_MANDLOCK) |
505 | return -EINVAL; | 532 | return -EINVAL; |
506 | 533 | ||
507 | if (!parse_fuse_opt((char *) data, &d)) | 534 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) |
508 | return -EINVAL; | 535 | return -EINVAL; |
509 | 536 | ||
510 | sb->s_blocksize = PAGE_CACHE_SIZE; | 537 | if (is_bdev) { |
511 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 538 | #ifdef CONFIG_BLOCK |
539 | if (!sb_set_blocksize(sb, d.blksize)) | ||
540 | return -EINVAL; | ||
541 | #endif | ||
542 | } else { | ||
543 | sb->s_blocksize = PAGE_CACHE_SIZE; | ||
544 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | ||
545 | } | ||
512 | sb->s_magic = FUSE_SUPER_MAGIC; | 546 | sb->s_magic = FUSE_SUPER_MAGIC; |
513 | sb->s_op = &fuse_super_operations; | 547 | sb->s_op = &fuse_super_operations; |
514 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 548 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
@@ -547,6 +581,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
547 | if (!init_req) | 581 | if (!init_req) |
548 | goto err_put_root; | 582 | goto err_put_root; |
549 | 583 | ||
584 | if (is_bdev) { | ||
585 | fc->destroy_req = fuse_request_alloc(); | ||
586 | if (!fc->destroy_req) | ||
587 | goto err_put_root; | ||
588 | } | ||
589 | |||
550 | mutex_lock(&fuse_mutex); | 590 | mutex_lock(&fuse_mutex); |
551 | err = -EINVAL; | 591 | err = -EINVAL; |
552 | if (file->private_data) | 592 | if (file->private_data) |
@@ -598,10 +638,47 @@ static struct file_system_type fuse_fs_type = { | |||
598 | .kill_sb = kill_anon_super, | 638 | .kill_sb = kill_anon_super, |
599 | }; | 639 | }; |
600 | 640 | ||
641 | #ifdef CONFIG_BLOCK | ||
642 | static int fuse_get_sb_blk(struct file_system_type *fs_type, | ||
643 | int flags, const char *dev_name, | ||
644 | void *raw_data, struct vfsmount *mnt) | ||
645 | { | ||
646 | return get_sb_bdev(fs_type, flags, dev_name, raw_data, fuse_fill_super, | ||
647 | mnt); | ||
648 | } | ||
649 | |||
650 | static struct file_system_type fuseblk_fs_type = { | ||
651 | .owner = THIS_MODULE, | ||
652 | .name = "fuseblk", | ||
653 | .get_sb = fuse_get_sb_blk, | ||
654 | .kill_sb = kill_block_super, | ||
655 | .fs_flags = FS_REQUIRES_DEV, | ||
656 | }; | ||
657 | |||
658 | static inline int register_fuseblk(void) | ||
659 | { | ||
660 | return register_filesystem(&fuseblk_fs_type); | ||
661 | } | ||
662 | |||
663 | static inline void unregister_fuseblk(void) | ||
664 | { | ||
665 | unregister_filesystem(&fuseblk_fs_type); | ||
666 | } | ||
667 | #else | ||
668 | static inline int register_fuseblk(void) | ||
669 | { | ||
670 | return 0; | ||
671 | } | ||
672 | |||
673 | static inline void unregister_fuseblk(void) | ||
674 | { | ||
675 | } | ||
676 | #endif | ||
677 | |||
601 | static decl_subsys(fuse, NULL, NULL); | 678 | static decl_subsys(fuse, NULL, NULL); |
602 | static decl_subsys(connections, NULL, NULL); | 679 | static decl_subsys(connections, NULL, NULL); |
603 | 680 | ||
604 | static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep, | 681 | static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep, |
605 | unsigned long flags) | 682 | unsigned long flags) |
606 | { | 683 | { |
607 | struct inode * inode = foo; | 684 | struct inode * inode = foo; |
@@ -617,24 +694,34 @@ static int __init fuse_fs_init(void) | |||
617 | 694 | ||
618 | err = register_filesystem(&fuse_fs_type); | 695 | err = register_filesystem(&fuse_fs_type); |
619 | if (err) | 696 | if (err) |
620 | printk("fuse: failed to register filesystem\n"); | 697 | goto out; |
621 | else { | ||
622 | fuse_inode_cachep = kmem_cache_create("fuse_inode", | ||
623 | sizeof(struct fuse_inode), | ||
624 | 0, SLAB_HWCACHE_ALIGN, | ||
625 | fuse_inode_init_once, NULL); | ||
626 | if (!fuse_inode_cachep) { | ||
627 | unregister_filesystem(&fuse_fs_type); | ||
628 | err = -ENOMEM; | ||
629 | } | ||
630 | } | ||
631 | 698 | ||
699 | err = register_fuseblk(); | ||
700 | if (err) | ||
701 | goto out_unreg; | ||
702 | |||
703 | fuse_inode_cachep = kmem_cache_create("fuse_inode", | ||
704 | sizeof(struct fuse_inode), | ||
705 | 0, SLAB_HWCACHE_ALIGN, | ||
706 | fuse_inode_init_once, NULL); | ||
707 | err = -ENOMEM; | ||
708 | if (!fuse_inode_cachep) | ||
709 | goto out_unreg2; | ||
710 | |||
711 | return 0; | ||
712 | |||
713 | out_unreg2: | ||
714 | unregister_fuseblk(); | ||
715 | out_unreg: | ||
716 | unregister_filesystem(&fuse_fs_type); | ||
717 | out: | ||
632 | return err; | 718 | return err; |
633 | } | 719 | } |
634 | 720 | ||
635 | static void fuse_fs_cleanup(void) | 721 | static void fuse_fs_cleanup(void) |
636 | { | 722 | { |
637 | unregister_filesystem(&fuse_fs_type); | 723 | unregister_filesystem(&fuse_fs_type); |
724 | unregister_fuseblk(); | ||
638 | kmem_cache_destroy(fuse_inode_cachep); | 725 | kmem_cache_destroy(fuse_inode_cachep); |
639 | } | 726 | } |
640 | 727 | ||
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index 8c27de8b9568..c0791cbacad9 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig | |||
@@ -2,6 +2,7 @@ config GFS2_FS | |||
2 | tristate "GFS2 file system support" | 2 | tristate "GFS2 file system support" |
3 | depends on EXPERIMENTAL | 3 | depends on EXPERIMENTAL |
4 | select FS_POSIX_ACL | 4 | select FS_POSIX_ACL |
5 | select CRC32 | ||
5 | help | 6 | help |
6 | A cluster filesystem. | 7 | A cluster filesystem. |
7 | 8 | ||
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 5f959b8ce406..6e80844367ee 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
@@ -74,11 +74,11 @@ int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access) | |||
74 | { | 74 | { |
75 | if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl) | 75 | if (!GFS2_SB(&ip->i_inode)->sd_args.ar_posix_acl) |
76 | return -EOPNOTSUPP; | 76 | return -EOPNOTSUPP; |
77 | if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER)) | 77 | if (current->fsuid != ip->i_inode.i_uid && !capable(CAP_FOWNER)) |
78 | return -EPERM; | 78 | return -EPERM; |
79 | if (S_ISLNK(ip->i_di.di_mode)) | 79 | if (S_ISLNK(ip->i_inode.i_mode)) |
80 | return -EOPNOTSUPP; | 80 | return -EOPNOTSUPP; |
81 | if (!access && !S_ISDIR(ip->i_di.di_mode)) | 81 | if (!access && !S_ISDIR(ip->i_inode.i_mode)) |
82 | return -EACCES; | 82 | return -EACCES; |
83 | 83 | ||
84 | return 0; | 84 | return 0; |
@@ -145,14 +145,14 @@ out: | |||
145 | } | 145 | } |
146 | 146 | ||
147 | /** | 147 | /** |
148 | * gfs2_check_acl_locked - Check an ACL to see if we're allowed to do something | 148 | * gfs2_check_acl - Check an ACL to see if we're allowed to do something |
149 | * @inode: the file we want to do something to | 149 | * @inode: the file we want to do something to |
150 | * @mask: what we want to do | 150 | * @mask: what we want to do |
151 | * | 151 | * |
152 | * Returns: errno | 152 | * Returns: errno |
153 | */ | 153 | */ |
154 | 154 | ||
155 | int gfs2_check_acl_locked(struct inode *inode, int mask) | 155 | int gfs2_check_acl(struct inode *inode, int mask) |
156 | { | 156 | { |
157 | struct posix_acl *acl = NULL; | 157 | struct posix_acl *acl = NULL; |
158 | int error; | 158 | int error; |
@@ -170,21 +170,6 @@ int gfs2_check_acl_locked(struct inode *inode, int mask) | |||
170 | return -EAGAIN; | 170 | return -EAGAIN; |
171 | } | 171 | } |
172 | 172 | ||
173 | int gfs2_check_acl(struct inode *inode, int mask) | ||
174 | { | ||
175 | struct gfs2_inode *ip = GFS2_I(inode); | ||
176 | struct gfs2_holder i_gh; | ||
177 | int error; | ||
178 | |||
179 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | ||
180 | if (!error) { | ||
181 | error = gfs2_check_acl_locked(inode, mask); | ||
182 | gfs2_glock_dq_uninit(&i_gh); | ||
183 | } | ||
184 | |||
185 | return error; | ||
186 | } | ||
187 | |||
188 | static int munge_mode(struct gfs2_inode *ip, mode_t mode) | 173 | static int munge_mode(struct gfs2_inode *ip, mode_t mode) |
189 | { | 174 | { |
190 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 175 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
@@ -198,10 +183,10 @@ static int munge_mode(struct gfs2_inode *ip, mode_t mode) | |||
198 | error = gfs2_meta_inode_buffer(ip, &dibh); | 183 | error = gfs2_meta_inode_buffer(ip, &dibh); |
199 | if (!error) { | 184 | if (!error) { |
200 | gfs2_assert_withdraw(sdp, | 185 | gfs2_assert_withdraw(sdp, |
201 | (ip->i_di.di_mode & S_IFMT) == (mode & S_IFMT)); | 186 | (ip->i_inode.i_mode & S_IFMT) == (mode & S_IFMT)); |
202 | ip->i_di.di_mode = mode; | 187 | ip->i_inode.i_mode = mode; |
203 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 188 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
204 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 189 | gfs2_dinode_out(ip, dibh->b_data); |
205 | brelse(dibh); | 190 | brelse(dibh); |
206 | } | 191 | } |
207 | 192 | ||
@@ -215,12 +200,12 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
215 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 200 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
216 | struct posix_acl *acl = NULL, *clone; | 201 | struct posix_acl *acl = NULL, *clone; |
217 | struct gfs2_ea_request er; | 202 | struct gfs2_ea_request er; |
218 | mode_t mode = ip->i_di.di_mode; | 203 | mode_t mode = ip->i_inode.i_mode; |
219 | int error; | 204 | int error; |
220 | 205 | ||
221 | if (!sdp->sd_args.ar_posix_acl) | 206 | if (!sdp->sd_args.ar_posix_acl) |
222 | return 0; | 207 | return 0; |
223 | if (S_ISLNK(ip->i_di.di_mode)) | 208 | if (S_ISLNK(ip->i_inode.i_mode)) |
224 | return 0; | 209 | return 0; |
225 | 210 | ||
226 | memset(&er, 0, sizeof(struct gfs2_ea_request)); | 211 | memset(&er, 0, sizeof(struct gfs2_ea_request)); |
@@ -232,7 +217,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
232 | return error; | 217 | return error; |
233 | if (!acl) { | 218 | if (!acl) { |
234 | mode &= ~current->fs->umask; | 219 | mode &= ~current->fs->umask; |
235 | if (mode != ip->i_di.di_mode) | 220 | if (mode != ip->i_inode.i_mode) |
236 | error = munge_mode(ip, mode); | 221 | error = munge_mode(ip, mode); |
237 | return error; | 222 | return error; |
238 | } | 223 | } |
@@ -244,7 +229,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
244 | posix_acl_release(acl); | 229 | posix_acl_release(acl); |
245 | acl = clone; | 230 | acl = clone; |
246 | 231 | ||
247 | if (S_ISDIR(ip->i_di.di_mode)) { | 232 | if (S_ISDIR(ip->i_inode.i_mode)) { |
248 | er.er_name = GFS2_POSIX_ACL_DEFAULT; | 233 | er.er_name = GFS2_POSIX_ACL_DEFAULT; |
249 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; | 234 | er.er_name_len = GFS2_POSIX_ACL_DEFAULT_LEN; |
250 | error = gfs2_system_eaops.eo_set(ip, &er); | 235 | error = gfs2_system_eaops.eo_set(ip, &er); |
diff --git a/fs/gfs2/acl.h b/fs/gfs2/acl.h index 05c294fe0d78..6751930bfb64 100644 --- a/fs/gfs2/acl.h +++ b/fs/gfs2/acl.h | |||
@@ -31,7 +31,6 @@ int gfs2_acl_validate_set(struct gfs2_inode *ip, int access, | |||
31 | struct gfs2_ea_request *er, | 31 | struct gfs2_ea_request *er, |
32 | int *remove, mode_t *mode); | 32 | int *remove, mode_t *mode); |
33 | int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access); | 33 | int gfs2_acl_validate_remove(struct gfs2_inode *ip, int access); |
34 | int gfs2_check_acl_locked(struct inode *inode, int mask); | ||
35 | int gfs2_check_acl(struct inode *inode, int mask); | 34 | int gfs2_check_acl(struct inode *inode, int mask); |
36 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip); | 35 | int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip); |
37 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); | 36 | int gfs2_acl_chmod(struct gfs2_inode *ip, struct iattr *attr); |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index 06e9a8cb45e9..8240c1ff94f4 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -38,8 +38,8 @@ struct metapath { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh, | 40 | typedef int (*block_call_t) (struct gfs2_inode *ip, struct buffer_head *dibh, |
41 | struct buffer_head *bh, u64 *top, | 41 | struct buffer_head *bh, __be64 *top, |
42 | u64 *bottom, unsigned int height, | 42 | __be64 *bottom, unsigned int height, |
43 | void *data); | 43 | void *data); |
44 | 44 | ||
45 | struct strip_mine { | 45 | struct strip_mine { |
@@ -163,6 +163,7 @@ int gfs2_unstuff_dinode(struct gfs2_inode *ip, struct page *page) | |||
163 | if (ip->i_di.di_size) { | 163 | if (ip->i_di.di_size) { |
164 | *(__be64 *)(di + 1) = cpu_to_be64(block); | 164 | *(__be64 *)(di + 1) = cpu_to_be64(block); |
165 | ip->i_di.di_blocks++; | 165 | ip->i_di.di_blocks++; |
166 | gfs2_set_inode_blocks(&ip->i_inode); | ||
166 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); | 167 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); |
167 | } | 168 | } |
168 | 169 | ||
@@ -230,7 +231,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
230 | struct buffer_head *blocks[GFS2_MAX_META_HEIGHT]; | 231 | struct buffer_head *blocks[GFS2_MAX_META_HEIGHT]; |
231 | struct gfs2_dinode *di; | 232 | struct gfs2_dinode *di; |
232 | int error; | 233 | int error; |
233 | u64 *bp; | 234 | __be64 *bp; |
234 | u64 bn; | 235 | u64 bn; |
235 | unsigned n; | 236 | unsigned n; |
236 | 237 | ||
@@ -255,7 +256,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
255 | GFS2_FORMAT_IN); | 256 | GFS2_FORMAT_IN); |
256 | gfs2_buffer_clear_tail(blocks[n], | 257 | gfs2_buffer_clear_tail(blocks[n], |
257 | sizeof(struct gfs2_meta_header)); | 258 | sizeof(struct gfs2_meta_header)); |
258 | bp = (u64 *)(blocks[n]->b_data + | 259 | bp = (__be64 *)(blocks[n]->b_data + |
259 | sizeof(struct gfs2_meta_header)); | 260 | sizeof(struct gfs2_meta_header)); |
260 | *bp = cpu_to_be64(blocks[n+1]->b_blocknr); | 261 | *bp = cpu_to_be64(blocks[n+1]->b_blocknr); |
261 | brelse(blocks[n]); | 262 | brelse(blocks[n]); |
@@ -272,6 +273,7 @@ static int build_height(struct inode *inode, unsigned height) | |||
272 | *(__be64 *)(di + 1) = cpu_to_be64(bn); | 273 | *(__be64 *)(di + 1) = cpu_to_be64(bn); |
273 | ip->i_di.di_height += new_height; | 274 | ip->i_di.di_height += new_height; |
274 | ip->i_di.di_blocks += new_height; | 275 | ip->i_di.di_blocks += new_height; |
276 | gfs2_set_inode_blocks(&ip->i_inode); | ||
275 | di->di_height = cpu_to_be16(ip->i_di.di_height); | 277 | di->di_height = cpu_to_be16(ip->i_di.di_height); |
276 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); | 278 | di->di_blocks = cpu_to_be64(ip->i_di.di_blocks); |
277 | brelse(dibh); | 279 | brelse(dibh); |
@@ -360,15 +362,15 @@ static void find_metapath(struct gfs2_inode *ip, u64 block, | |||
360 | * metadata tree. | 362 | * metadata tree. |
361 | */ | 363 | */ |
362 | 364 | ||
363 | static inline u64 *metapointer(struct buffer_head *bh, int *boundary, | 365 | static inline __be64 *metapointer(struct buffer_head *bh, int *boundary, |
364 | unsigned int height, const struct metapath *mp) | 366 | unsigned int height, const struct metapath *mp) |
365 | { | 367 | { |
366 | unsigned int head_size = (height > 0) ? | 368 | unsigned int head_size = (height > 0) ? |
367 | sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); | 369 | sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); |
368 | u64 *ptr; | 370 | __be64 *ptr; |
369 | *boundary = 0; | 371 | *boundary = 0; |
370 | ptr = ((u64 *)(bh->b_data + head_size)) + mp->mp_list[height]; | 372 | ptr = ((__be64 *)(bh->b_data + head_size)) + mp->mp_list[height]; |
371 | if (ptr + 1 == (u64 *)(bh->b_data + bh->b_size)) | 373 | if (ptr + 1 == (__be64 *)(bh->b_data + bh->b_size)) |
372 | *boundary = 1; | 374 | *boundary = 1; |
373 | return ptr; | 375 | return ptr; |
374 | } | 376 | } |
@@ -394,7 +396,7 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
394 | int *new, u64 *block) | 396 | int *new, u64 *block) |
395 | { | 397 | { |
396 | int boundary; | 398 | int boundary; |
397 | u64 *ptr = metapointer(bh, &boundary, height, mp); | 399 | __be64 *ptr = metapointer(bh, &boundary, height, mp); |
398 | 400 | ||
399 | if (*ptr) { | 401 | if (*ptr) { |
400 | *block = be64_to_cpu(*ptr); | 402 | *block = be64_to_cpu(*ptr); |
@@ -415,17 +417,35 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
415 | 417 | ||
416 | *ptr = cpu_to_be64(*block); | 418 | *ptr = cpu_to_be64(*block); |
417 | ip->i_di.di_blocks++; | 419 | ip->i_di.di_blocks++; |
420 | gfs2_set_inode_blocks(&ip->i_inode); | ||
418 | 421 | ||
419 | *new = 1; | 422 | *new = 1; |
420 | return 0; | 423 | return 0; |
421 | } | 424 | } |
422 | 425 | ||
426 | static inline void bmap_lock(struct inode *inode, int create) | ||
427 | { | ||
428 | struct gfs2_inode *ip = GFS2_I(inode); | ||
429 | if (create) | ||
430 | down_write(&ip->i_rw_mutex); | ||
431 | else | ||
432 | down_read(&ip->i_rw_mutex); | ||
433 | } | ||
434 | |||
435 | static inline void bmap_unlock(struct inode *inode, int create) | ||
436 | { | ||
437 | struct gfs2_inode *ip = GFS2_I(inode); | ||
438 | if (create) | ||
439 | up_write(&ip->i_rw_mutex); | ||
440 | else | ||
441 | up_read(&ip->i_rw_mutex); | ||
442 | } | ||
443 | |||
423 | /** | 444 | /** |
424 | * gfs2_block_pointers - Map a block from an inode to a disk block | 445 | * gfs2_block_map - Map a block from an inode to a disk block |
425 | * @inode: The inode | 446 | * @inode: The inode |
426 | * @lblock: The logical block number | 447 | * @lblock: The logical block number |
427 | * @map_bh: The bh to be mapped | 448 | * @bh_map: The bh to be mapped |
428 | * @mp: metapath to use | ||
429 | * | 449 | * |
430 | * Find the block number on the current device which corresponds to an | 450 | * Find the block number on the current device which corresponds to an |
431 | * inode's block. If the block had to be created, "new" will be set. | 451 | * inode's block. If the block had to be created, "new" will be set. |
@@ -433,8 +453,8 @@ static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
433 | * Returns: errno | 453 | * Returns: errno |
434 | */ | 454 | */ |
435 | 455 | ||
436 | static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | 456 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, |
437 | struct buffer_head *bh_map, struct metapath *mp) | 457 | struct buffer_head *bh_map) |
438 | { | 458 | { |
439 | struct gfs2_inode *ip = GFS2_I(inode); | 459 | struct gfs2_inode *ip = GFS2_I(inode); |
440 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 460 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -448,57 +468,61 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
448 | u64 dblock = 0; | 468 | u64 dblock = 0; |
449 | int boundary; | 469 | int boundary; |
450 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; | 470 | unsigned int maxlen = bh_map->b_size >> inode->i_blkbits; |
471 | struct metapath mp; | ||
472 | u64 size; | ||
451 | 473 | ||
452 | BUG_ON(maxlen == 0); | 474 | BUG_ON(maxlen == 0); |
453 | 475 | ||
454 | if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) | 476 | if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) |
455 | return 0; | 477 | return 0; |
456 | 478 | ||
479 | bmap_lock(inode, create); | ||
480 | clear_buffer_mapped(bh_map); | ||
481 | clear_buffer_new(bh_map); | ||
482 | clear_buffer_boundary(bh_map); | ||
457 | bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; | 483 | bsize = gfs2_is_dir(ip) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; |
458 | 484 | size = (lblock + 1) * bsize; | |
459 | height = calc_tree_height(ip, (lblock + 1) * bsize); | 485 | |
460 | if (ip->i_di.di_height < height) { | 486 | if (size > ip->i_di.di_size) { |
461 | if (!create) | 487 | height = calc_tree_height(ip, size); |
462 | return 0; | 488 | if (ip->i_di.di_height < height) { |
463 | 489 | if (!create) | |
464 | error = build_height(inode, height); | 490 | goto out_ok; |
465 | if (error) | 491 | |
466 | return error; | 492 | error = build_height(inode, height); |
493 | if (error) | ||
494 | goto out_fail; | ||
495 | } | ||
467 | } | 496 | } |
468 | 497 | ||
469 | find_metapath(ip, lblock, mp); | 498 | find_metapath(ip, lblock, &mp); |
470 | end_of_metadata = ip->i_di.di_height - 1; | 499 | end_of_metadata = ip->i_di.di_height - 1; |
471 | |||
472 | error = gfs2_meta_inode_buffer(ip, &bh); | 500 | error = gfs2_meta_inode_buffer(ip, &bh); |
473 | if (error) | 501 | if (error) |
474 | return error; | 502 | goto out_fail; |
475 | 503 | ||
476 | for (x = 0; x < end_of_metadata; x++) { | 504 | for (x = 0; x < end_of_metadata; x++) { |
477 | lookup_block(ip, bh, x, mp, create, &new, &dblock); | 505 | lookup_block(ip, bh, x, &mp, create, &new, &dblock); |
478 | brelse(bh); | 506 | brelse(bh); |
479 | if (!dblock) | 507 | if (!dblock) |
480 | return 0; | 508 | goto out_ok; |
481 | 509 | ||
482 | error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh); | 510 | error = gfs2_meta_indirect_buffer(ip, x+1, dblock, new, &bh); |
483 | if (error) | 511 | if (error) |
484 | return error; | 512 | goto out_fail; |
485 | } | 513 | } |
486 | 514 | ||
487 | boundary = lookup_block(ip, bh, end_of_metadata, mp, create, &new, &dblock); | 515 | boundary = lookup_block(ip, bh, end_of_metadata, &mp, create, &new, &dblock); |
488 | clear_buffer_mapped(bh_map); | ||
489 | clear_buffer_new(bh_map); | ||
490 | clear_buffer_boundary(bh_map); | ||
491 | |||
492 | if (dblock) { | 516 | if (dblock) { |
493 | map_bh(bh_map, inode->i_sb, dblock); | 517 | map_bh(bh_map, inode->i_sb, dblock); |
494 | if (boundary) | 518 | if (boundary) |
495 | set_buffer_boundary(bh); | 519 | set_buffer_boundary(bh_map); |
496 | if (new) { | 520 | if (new) { |
497 | struct buffer_head *dibh; | 521 | struct buffer_head *dibh; |
498 | error = gfs2_meta_inode_buffer(ip, &dibh); | 522 | error = gfs2_meta_inode_buffer(ip, &dibh); |
499 | if (!error) { | 523 | if (!error) { |
500 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 524 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
501 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 525 | gfs2_dinode_out(ip, dibh->b_data); |
502 | brelse(dibh); | 526 | brelse(dibh); |
503 | } | 527 | } |
504 | set_buffer_new(bh_map); | 528 | set_buffer_new(bh_map); |
@@ -507,8 +531,8 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
507 | while(--maxlen && !buffer_boundary(bh_map)) { | 531 | while(--maxlen && !buffer_boundary(bh_map)) { |
508 | u64 eblock; | 532 | u64 eblock; |
509 | 533 | ||
510 | mp->mp_list[end_of_metadata]++; | 534 | mp.mp_list[end_of_metadata]++; |
511 | boundary = lookup_block(ip, bh, end_of_metadata, mp, 0, &new, &eblock); | 535 | boundary = lookup_block(ip, bh, end_of_metadata, &mp, 0, &new, &eblock); |
512 | if (eblock != ++dblock) | 536 | if (eblock != ++dblock) |
513 | break; | 537 | break; |
514 | bh_map->b_size += (1 << inode->i_blkbits); | 538 | bh_map->b_size += (1 << inode->i_blkbits); |
@@ -518,43 +542,15 @@ static int gfs2_block_pointers(struct inode *inode, u64 lblock, int create, | |||
518 | } | 542 | } |
519 | out_brelse: | 543 | out_brelse: |
520 | brelse(bh); | 544 | brelse(bh); |
521 | return 0; | 545 | out_ok: |
522 | } | 546 | error = 0; |
523 | 547 | out_fail: | |
524 | |||
525 | static inline void bmap_lock(struct inode *inode, int create) | ||
526 | { | ||
527 | struct gfs2_inode *ip = GFS2_I(inode); | ||
528 | if (create) | ||
529 | down_write(&ip->i_rw_mutex); | ||
530 | else | ||
531 | down_read(&ip->i_rw_mutex); | ||
532 | } | ||
533 | |||
534 | static inline void bmap_unlock(struct inode *inode, int create) | ||
535 | { | ||
536 | struct gfs2_inode *ip = GFS2_I(inode); | ||
537 | if (create) | ||
538 | up_write(&ip->i_rw_mutex); | ||
539 | else | ||
540 | up_read(&ip->i_rw_mutex); | ||
541 | } | ||
542 | |||
543 | int gfs2_block_map(struct inode *inode, u64 lblock, int create, | ||
544 | struct buffer_head *bh) | ||
545 | { | ||
546 | struct metapath mp; | ||
547 | int ret; | ||
548 | |||
549 | bmap_lock(inode, create); | ||
550 | ret = gfs2_block_pointers(inode, lblock, create, bh, &mp); | ||
551 | bmap_unlock(inode, create); | 548 | bmap_unlock(inode, create); |
552 | return ret; | 549 | return error; |
553 | } | 550 | } |
554 | 551 | ||
555 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) | 552 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) |
556 | { | 553 | { |
557 | struct metapath mp; | ||
558 | struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 }; | 554 | struct buffer_head bh = { .b_state = 0, .b_blocknr = 0 }; |
559 | int ret; | 555 | int ret; |
560 | int create = *new; | 556 | int create = *new; |
@@ -564,9 +560,7 @@ int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsi | |||
564 | BUG_ON(!new); | 560 | BUG_ON(!new); |
565 | 561 | ||
566 | bh.b_size = 1 << (inode->i_blkbits + 5); | 562 | bh.b_size = 1 << (inode->i_blkbits + 5); |
567 | bmap_lock(inode, create); | 563 | ret = gfs2_block_map(inode, lblock, create, &bh); |
568 | ret = gfs2_block_pointers(inode, lblock, create, &bh, &mp); | ||
569 | bmap_unlock(inode, create); | ||
570 | *extlen = bh.b_size >> inode->i_blkbits; | 564 | *extlen = bh.b_size >> inode->i_blkbits; |
571 | *dblock = bh.b_blocknr; | 565 | *dblock = bh.b_blocknr; |
572 | if (buffer_new(&bh)) | 566 | if (buffer_new(&bh)) |
@@ -600,7 +594,7 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
600 | { | 594 | { |
601 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 595 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
602 | struct buffer_head *bh = NULL; | 596 | struct buffer_head *bh = NULL; |
603 | u64 *top, *bottom; | 597 | __be64 *top, *bottom; |
604 | u64 bn; | 598 | u64 bn; |
605 | int error; | 599 | int error; |
606 | int mh_size = sizeof(struct gfs2_meta_header); | 600 | int mh_size = sizeof(struct gfs2_meta_header); |
@@ -611,17 +605,17 @@ static int recursive_scan(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
611 | return error; | 605 | return error; |
612 | dibh = bh; | 606 | dibh = bh; |
613 | 607 | ||
614 | top = (u64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0]; | 608 | top = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + mp->mp_list[0]; |
615 | bottom = (u64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs; | 609 | bottom = (__be64 *)(bh->b_data + sizeof(struct gfs2_dinode)) + sdp->sd_diptrs; |
616 | } else { | 610 | } else { |
617 | error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh); | 611 | error = gfs2_meta_indirect_buffer(ip, height, block, 0, &bh); |
618 | if (error) | 612 | if (error) |
619 | return error; | 613 | return error; |
620 | 614 | ||
621 | top = (u64 *)(bh->b_data + mh_size) + | 615 | top = (__be64 *)(bh->b_data + mh_size) + |
622 | (first ? mp->mp_list[height] : 0); | 616 | (first ? mp->mp_list[height] : 0); |
623 | 617 | ||
624 | bottom = (u64 *)(bh->b_data + mh_size) + sdp->sd_inptrs; | 618 | bottom = (__be64 *)(bh->b_data + mh_size) + sdp->sd_inptrs; |
625 | } | 619 | } |
626 | 620 | ||
627 | error = bc(ip, dibh, bh, top, bottom, height, data); | 621 | error = bc(ip, dibh, bh, top, bottom, height, data); |
@@ -660,7 +654,7 @@ out: | |||
660 | */ | 654 | */ |
661 | 655 | ||
662 | static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | 656 | static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, |
663 | struct buffer_head *bh, u64 *top, u64 *bottom, | 657 | struct buffer_head *bh, __be64 *top, __be64 *bottom, |
664 | unsigned int height, void *data) | 658 | unsigned int height, void *data) |
665 | { | 659 | { |
666 | struct strip_mine *sm = data; | 660 | struct strip_mine *sm = data; |
@@ -668,7 +662,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
668 | struct gfs2_rgrp_list rlist; | 662 | struct gfs2_rgrp_list rlist; |
669 | u64 bn, bstart; | 663 | u64 bn, bstart; |
670 | u32 blen; | 664 | u32 blen; |
671 | u64 *p; | 665 | __be64 *p; |
672 | unsigned int rg_blocks = 0; | 666 | unsigned int rg_blocks = 0; |
673 | int metadata; | 667 | int metadata; |
674 | unsigned int revokes = 0; | 668 | unsigned int revokes = 0; |
@@ -770,6 +764,7 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
770 | if (!ip->i_di.di_blocks) | 764 | if (!ip->i_di.di_blocks) |
771 | gfs2_consist_inode(ip); | 765 | gfs2_consist_inode(ip); |
772 | ip->i_di.di_blocks--; | 766 | ip->i_di.di_blocks--; |
767 | gfs2_set_inode_blocks(&ip->i_inode); | ||
773 | } | 768 | } |
774 | if (bstart) { | 769 | if (bstart) { |
775 | if (metadata) | 770 | if (metadata) |
@@ -778,9 +773,9 @@ static int do_strip(struct gfs2_inode *ip, struct buffer_head *dibh, | |||
778 | gfs2_free_data(ip, bstart, blen); | 773 | gfs2_free_data(ip, bstart, blen); |
779 | } | 774 | } |
780 | 775 | ||
781 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 776 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
782 | 777 | ||
783 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 778 | gfs2_dinode_out(ip, dibh->b_data); |
784 | 779 | ||
785 | up_write(&ip->i_rw_mutex); | 780 | up_write(&ip->i_rw_mutex); |
786 | 781 | ||
@@ -819,7 +814,7 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
819 | if (error) | 814 | if (error) |
820 | goto out; | 815 | goto out; |
821 | 816 | ||
822 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 817 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
823 | if (error) | 818 | if (error) |
824 | goto out_gunlock_q; | 819 | goto out_gunlock_q; |
825 | 820 | ||
@@ -853,14 +848,14 @@ static int do_grow(struct gfs2_inode *ip, u64 size) | |||
853 | } | 848 | } |
854 | 849 | ||
855 | ip->i_di.di_size = size; | 850 | ip->i_di.di_size = size; |
856 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 851 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
857 | 852 | ||
858 | error = gfs2_meta_inode_buffer(ip, &dibh); | 853 | error = gfs2_meta_inode_buffer(ip, &dibh); |
859 | if (error) | 854 | if (error) |
860 | goto out_end_trans; | 855 | goto out_end_trans; |
861 | 856 | ||
862 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 857 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
863 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 858 | gfs2_dinode_out(ip, dibh->b_data); |
864 | brelse(dibh); | 859 | brelse(dibh); |
865 | 860 | ||
866 | out_end_trans: | 861 | out_end_trans: |
@@ -968,9 +963,9 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
968 | 963 | ||
969 | if (gfs2_is_stuffed(ip)) { | 964 | if (gfs2_is_stuffed(ip)) { |
970 | ip->i_di.di_size = size; | 965 | ip->i_di.di_size = size; |
971 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 966 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
972 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 967 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
973 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 968 | gfs2_dinode_out(ip, dibh->b_data); |
974 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); | 969 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode) + size); |
975 | error = 1; | 970 | error = 1; |
976 | 971 | ||
@@ -980,10 +975,10 @@ static int trunc_start(struct gfs2_inode *ip, u64 size) | |||
980 | 975 | ||
981 | if (!error) { | 976 | if (!error) { |
982 | ip->i_di.di_size = size; | 977 | ip->i_di.di_size = size; |
983 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 978 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
984 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; | 979 | ip->i_di.di_flags |= GFS2_DIF_TRUNC_IN_PROG; |
985 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 980 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
986 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 981 | gfs2_dinode_out(ip, dibh->b_data); |
987 | } | 982 | } |
988 | } | 983 | } |
989 | 984 | ||
@@ -1053,11 +1048,11 @@ static int trunc_end(struct gfs2_inode *ip) | |||
1053 | ip->i_num.no_addr; | 1048 | ip->i_num.no_addr; |
1054 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 1049 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
1055 | } | 1050 | } |
1056 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 1051 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1057 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; | 1052 | ip->i_di.di_flags &= ~GFS2_DIF_TRUNC_IN_PROG; |
1058 | 1053 | ||
1059 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1054 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1060 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1055 | gfs2_dinode_out(ip, dibh->b_data); |
1061 | brelse(dibh); | 1056 | brelse(dibh); |
1062 | 1057 | ||
1063 | out: | 1058 | out: |
@@ -1109,7 +1104,7 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size) | |||
1109 | { | 1104 | { |
1110 | int error; | 1105 | int error; |
1111 | 1106 | ||
1112 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_di.di_mode))) | 1107 | if (gfs2_assert_warn(GFS2_SB(&ip->i_inode), S_ISREG(ip->i_inode.i_mode))) |
1113 | return -EINVAL; | 1108 | return -EINVAL; |
1114 | 1109 | ||
1115 | if (size > ip->i_di.di_size) | 1110 | if (size > ip->i_di.di_size) |
diff --git a/fs/gfs2/daemon.c b/fs/gfs2/daemon.c index cab1f68d4685..683cb5bda870 100644 --- a/fs/gfs2/daemon.c +++ b/fs/gfs2/daemon.c | |||
@@ -112,6 +112,7 @@ int gfs2_logd(void *data) | |||
112 | struct gfs2_sbd *sdp = data; | 112 | struct gfs2_sbd *sdp = data; |
113 | struct gfs2_holder ji_gh; | 113 | struct gfs2_holder ji_gh; |
114 | unsigned long t; | 114 | unsigned long t; |
115 | int need_flush; | ||
115 | 116 | ||
116 | while (!kthread_should_stop()) { | 117 | while (!kthread_should_stop()) { |
117 | /* Advance the log tail */ | 118 | /* Advance the log tail */ |
@@ -120,8 +121,10 @@ int gfs2_logd(void *data) | |||
120 | gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; | 121 | gfs2_tune_get(sdp, gt_log_flush_secs) * HZ; |
121 | 122 | ||
122 | gfs2_ail1_empty(sdp, DIO_ALL); | 123 | gfs2_ail1_empty(sdp, DIO_ALL); |
123 | 124 | gfs2_log_lock(sdp); | |
124 | if (time_after_eq(jiffies, t)) { | 125 | need_flush = sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks); |
126 | gfs2_log_unlock(sdp); | ||
127 | if (need_flush || time_after_eq(jiffies, t)) { | ||
125 | gfs2_log_flush(sdp, NULL); | 128 | gfs2_log_flush(sdp, NULL); |
126 | sdp->sd_log_flush_time = jiffies; | 129 | sdp->sd_log_flush_time = jiffies; |
127 | } | 130 | } |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index e24af28b1a12..0fdcb7713cd9 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -131,8 +131,8 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf, | |||
131 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); | 131 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); |
132 | if (ip->i_di.di_size < offset + size) | 132 | if (ip->i_di.di_size < offset + size) |
133 | ip->i_di.di_size = offset + size; | 133 | ip->i_di.di_size = offset + size; |
134 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 134 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
135 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 135 | gfs2_dinode_out(ip, dibh->b_data); |
136 | 136 | ||
137 | brelse(dibh); | 137 | brelse(dibh); |
138 | 138 | ||
@@ -229,10 +229,10 @@ out: | |||
229 | 229 | ||
230 | if (ip->i_di.di_size < offset + copied) | 230 | if (ip->i_di.di_size < offset + copied) |
231 | ip->i_di.di_size = offset + copied; | 231 | ip->i_di.di_size = offset + copied; |
232 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 232 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
233 | 233 | ||
234 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 234 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
235 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 235 | gfs2_dinode_out(ip, dibh->b_data); |
236 | brelse(dibh); | 236 | brelse(dibh); |
237 | 237 | ||
238 | return copied; | 238 | return copied; |
@@ -340,10 +340,15 @@ fail: | |||
340 | return (copied) ? copied : error; | 340 | return (copied) ? copied : error; |
341 | } | 341 | } |
342 | 342 | ||
343 | static inline int gfs2_dirent_sentinel(const struct gfs2_dirent *dent) | ||
344 | { | ||
345 | return dent->de_inum.no_addr == 0 || dent->de_inum.no_formal_ino == 0; | ||
346 | } | ||
347 | |||
343 | static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent, | 348 | static inline int __gfs2_dirent_find(const struct gfs2_dirent *dent, |
344 | const struct qstr *name, int ret) | 349 | const struct qstr *name, int ret) |
345 | { | 350 | { |
346 | if (dent->de_inum.no_addr != 0 && | 351 | if (!gfs2_dirent_sentinel(dent) && |
347 | be32_to_cpu(dent->de_hash) == name->hash && | 352 | be32_to_cpu(dent->de_hash) == name->hash && |
348 | be16_to_cpu(dent->de_name_len) == name->len && | 353 | be16_to_cpu(dent->de_name_len) == name->len && |
349 | memcmp(dent+1, name->name, name->len) == 0) | 354 | memcmp(dent+1, name->name, name->len) == 0) |
@@ -388,7 +393,7 @@ static int gfs2_dirent_find_space(const struct gfs2_dirent *dent, | |||
388 | unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); | 393 | unsigned actual = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); |
389 | unsigned totlen = be16_to_cpu(dent->de_rec_len); | 394 | unsigned totlen = be16_to_cpu(dent->de_rec_len); |
390 | 395 | ||
391 | if (!dent->de_inum.no_addr) | 396 | if (gfs2_dirent_sentinel(dent)) |
392 | actual = GFS2_DIRENT_SIZE(0); | 397 | actual = GFS2_DIRENT_SIZE(0); |
393 | if (totlen - actual >= required) | 398 | if (totlen - actual >= required) |
394 | return 1; | 399 | return 1; |
@@ -405,7 +410,7 @@ static int gfs2_dirent_gather(const struct gfs2_dirent *dent, | |||
405 | void *opaque) | 410 | void *opaque) |
406 | { | 411 | { |
407 | struct dirent_gather *g = opaque; | 412 | struct dirent_gather *g = opaque; |
408 | if (dent->de_inum.no_addr) { | 413 | if (!gfs2_dirent_sentinel(dent)) { |
409 | g->pdent[g->offset++] = dent; | 414 | g->pdent[g->offset++] = dent; |
410 | } | 415 | } |
411 | return 0; | 416 | return 0; |
@@ -433,10 +438,10 @@ static int gfs2_check_dirent(struct gfs2_dirent *dent, unsigned int offset, | |||
433 | if (unlikely(offset + size > len)) | 438 | if (unlikely(offset + size > len)) |
434 | goto error; | 439 | goto error; |
435 | msg = "zero inode number"; | 440 | msg = "zero inode number"; |
436 | if (unlikely(!first && !dent->de_inum.no_addr)) | 441 | if (unlikely(!first && gfs2_dirent_sentinel(dent))) |
437 | goto error; | 442 | goto error; |
438 | msg = "name length is greater than space in dirent"; | 443 | msg = "name length is greater than space in dirent"; |
439 | if (dent->de_inum.no_addr && | 444 | if (!gfs2_dirent_sentinel(dent) && |
440 | unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) > | 445 | unlikely(sizeof(struct gfs2_dirent)+be16_to_cpu(dent->de_name_len) > |
441 | size)) | 446 | size)) |
442 | goto error; | 447 | goto error; |
@@ -598,7 +603,7 @@ static int dirent_next(struct gfs2_inode *dip, struct buffer_head *bh, | |||
598 | return ret; | 603 | return ret; |
599 | 604 | ||
600 | /* Only the first dent could ever have de_inum.no_addr == 0 */ | 605 | /* Only the first dent could ever have de_inum.no_addr == 0 */ |
601 | if (!tmp->de_inum.no_addr) { | 606 | if (gfs2_dirent_sentinel(tmp)) { |
602 | gfs2_consist_inode(dip); | 607 | gfs2_consist_inode(dip); |
603 | return -EIO; | 608 | return -EIO; |
604 | } | 609 | } |
@@ -621,7 +626,7 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh, | |||
621 | { | 626 | { |
622 | u16 cur_rec_len, prev_rec_len; | 627 | u16 cur_rec_len, prev_rec_len; |
623 | 628 | ||
624 | if (!cur->de_inum.no_addr) { | 629 | if (gfs2_dirent_sentinel(cur)) { |
625 | gfs2_consist_inode(dip); | 630 | gfs2_consist_inode(dip); |
626 | return; | 631 | return; |
627 | } | 632 | } |
@@ -633,7 +638,8 @@ static void dirent_del(struct gfs2_inode *dip, struct buffer_head *bh, | |||
633 | out the inode number and return. */ | 638 | out the inode number and return. */ |
634 | 639 | ||
635 | if (!prev) { | 640 | if (!prev) { |
636 | cur->de_inum.no_addr = 0; /* No endianess worries */ | 641 | cur->de_inum.no_addr = 0; |
642 | cur->de_inum.no_formal_ino = 0; | ||
637 | return; | 643 | return; |
638 | } | 644 | } |
639 | 645 | ||
@@ -664,7 +670,7 @@ static struct gfs2_dirent *gfs2_init_dirent(struct inode *inode, | |||
664 | struct gfs2_dirent *ndent; | 670 | struct gfs2_dirent *ndent; |
665 | unsigned offset = 0, totlen; | 671 | unsigned offset = 0, totlen; |
666 | 672 | ||
667 | if (dent->de_inum.no_addr) | 673 | if (!gfs2_dirent_sentinel(dent)) |
668 | offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); | 674 | offset = GFS2_DIRENT_SIZE(be16_to_cpu(dent->de_name_len)); |
669 | totlen = be16_to_cpu(dent->de_rec_len); | 675 | totlen = be16_to_cpu(dent->de_rec_len); |
670 | BUG_ON(offset + name->len > totlen); | 676 | BUG_ON(offset + name->len > totlen); |
@@ -713,12 +719,12 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, | |||
713 | static int get_leaf_nr(struct gfs2_inode *dip, u32 index, | 719 | static int get_leaf_nr(struct gfs2_inode *dip, u32 index, |
714 | u64 *leaf_out) | 720 | u64 *leaf_out) |
715 | { | 721 | { |
716 | u64 leaf_no; | 722 | __be64 leaf_no; |
717 | int error; | 723 | int error; |
718 | 724 | ||
719 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, | 725 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, |
720 | index * sizeof(u64), | 726 | index * sizeof(__be64), |
721 | sizeof(u64), 0); | 727 | sizeof(__be64), 0); |
722 | if (error != sizeof(u64)) | 728 | if (error != sizeof(u64)) |
723 | return (error < 0) ? error : -EIO; | 729 | return (error < 0) ? error : -EIO; |
724 | 730 | ||
@@ -837,7 +843,8 @@ static int dir_make_exhash(struct inode *inode) | |||
837 | struct gfs2_leaf *leaf; | 843 | struct gfs2_leaf *leaf; |
838 | int y; | 844 | int y; |
839 | u32 x; | 845 | u32 x; |
840 | u64 *lp, bn; | 846 | __be64 *lp; |
847 | u64 bn; | ||
841 | int error; | 848 | int error; |
842 | 849 | ||
843 | error = gfs2_meta_inode_buffer(dip, &dibh); | 850 | error = gfs2_meta_inode_buffer(dip, &dibh); |
@@ -893,20 +900,20 @@ static int dir_make_exhash(struct inode *inode) | |||
893 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); | 900 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); |
894 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); | 901 | gfs2_buffer_clear_tail(dibh, sizeof(struct gfs2_dinode)); |
895 | 902 | ||
896 | lp = (u64 *)(dibh->b_data + sizeof(struct gfs2_dinode)); | 903 | lp = (__be64 *)(dibh->b_data + sizeof(struct gfs2_dinode)); |
897 | 904 | ||
898 | for (x = sdp->sd_hash_ptrs; x--; lp++) | 905 | for (x = sdp->sd_hash_ptrs; x--; lp++) |
899 | *lp = cpu_to_be64(bn); | 906 | *lp = cpu_to_be64(bn); |
900 | 907 | ||
901 | dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; | 908 | dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; |
902 | dip->i_di.di_blocks++; | 909 | dip->i_di.di_blocks++; |
910 | gfs2_set_inode_blocks(&dip->i_inode); | ||
903 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; | 911 | dip->i_di.di_flags |= GFS2_DIF_EXHASH; |
904 | dip->i_di.di_payload_format = 0; | ||
905 | 912 | ||
906 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; | 913 | for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; |
907 | dip->i_di.di_depth = y; | 914 | dip->i_di.di_depth = y; |
908 | 915 | ||
909 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 916 | gfs2_dinode_out(dip, dibh->b_data); |
910 | 917 | ||
911 | brelse(dibh); | 918 | brelse(dibh); |
912 | 919 | ||
@@ -929,7 +936,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
929 | struct gfs2_leaf *nleaf, *oleaf; | 936 | struct gfs2_leaf *nleaf, *oleaf; |
930 | struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new; | 937 | struct gfs2_dirent *dent = NULL, *prev = NULL, *next = NULL, *new; |
931 | u32 start, len, half_len, divider; | 938 | u32 start, len, half_len, divider; |
932 | u64 bn, *lp, leaf_no; | 939 | u64 bn, leaf_no; |
940 | __be64 *lp; | ||
933 | u32 index; | 941 | u32 index; |
934 | int x, moved = 0; | 942 | int x, moved = 0; |
935 | int error; | 943 | int error; |
@@ -974,7 +982,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
974 | /* Change the pointers. | 982 | /* Change the pointers. |
975 | Don't bother distinguishing stuffed from non-stuffed. | 983 | Don't bother distinguishing stuffed from non-stuffed. |
976 | This code is complicated enough already. */ | 984 | This code is complicated enough already. */ |
977 | lp = kmalloc(half_len * sizeof(u64), GFP_NOFS | __GFP_NOFAIL); | 985 | lp = kmalloc(half_len * sizeof(__be64), GFP_NOFS | __GFP_NOFAIL); |
978 | /* Change the pointers */ | 986 | /* Change the pointers */ |
979 | for (x = 0; x < half_len; x++) | 987 | for (x = 0; x < half_len; x++) |
980 | lp[x] = cpu_to_be64(bn); | 988 | lp[x] = cpu_to_be64(bn); |
@@ -1000,7 +1008,7 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
1000 | if (dirent_next(dip, obh, &next)) | 1008 | if (dirent_next(dip, obh, &next)) |
1001 | next = NULL; | 1009 | next = NULL; |
1002 | 1010 | ||
1003 | if (dent->de_inum.no_addr && | 1011 | if (!gfs2_dirent_sentinel(dent) && |
1004 | be32_to_cpu(dent->de_hash) < divider) { | 1012 | be32_to_cpu(dent->de_hash) < divider) { |
1005 | struct qstr str; | 1013 | struct qstr str; |
1006 | str.name = (char*)(dent+1); | 1014 | str.name = (char*)(dent+1); |
@@ -1037,7 +1045,8 @@ static int dir_split_leaf(struct inode *inode, const struct qstr *name) | |||
1037 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1045 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1038 | if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) { | 1046 | if (!gfs2_assert_withdraw(GFS2_SB(&dip->i_inode), !error)) { |
1039 | dip->i_di.di_blocks++; | 1047 | dip->i_di.di_blocks++; |
1040 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1048 | gfs2_set_inode_blocks(&dip->i_inode); |
1049 | gfs2_dinode_out(dip, dibh->b_data); | ||
1041 | brelse(dibh); | 1050 | brelse(dibh); |
1042 | } | 1051 | } |
1043 | 1052 | ||
@@ -1117,7 +1126,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1117 | error = gfs2_meta_inode_buffer(dip, &dibh); | 1126 | error = gfs2_meta_inode_buffer(dip, &dibh); |
1118 | if (!gfs2_assert_withdraw(sdp, !error)) { | 1127 | if (!gfs2_assert_withdraw(sdp, !error)) { |
1119 | dip->i_di.di_depth++; | 1128 | dip->i_di.di_depth++; |
1120 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1129 | gfs2_dinode_out(dip, dibh->b_data); |
1121 | brelse(dibh); | 1130 | brelse(dibh); |
1122 | } | 1131 | } |
1123 | 1132 | ||
@@ -1194,7 +1203,7 @@ static int do_filldir_main(struct gfs2_inode *dip, u64 *offset, | |||
1194 | int *copied) | 1203 | int *copied) |
1195 | { | 1204 | { |
1196 | const struct gfs2_dirent *dent, *dent_next; | 1205 | const struct gfs2_dirent *dent, *dent_next; |
1197 | struct gfs2_inum inum; | 1206 | struct gfs2_inum_host inum; |
1198 | u64 off, off_next; | 1207 | u64 off, off_next; |
1199 | unsigned int x, y; | 1208 | unsigned int x, y; |
1200 | int run = 0; | 1209 | int run = 0; |
@@ -1341,7 +1350,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1341 | u32 hsize, len = 0; | 1350 | u32 hsize, len = 0; |
1342 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | 1351 | u32 ht_offset, lp_offset, ht_offset_cur = -1; |
1343 | u32 hash, index; | 1352 | u32 hash, index; |
1344 | u64 *lp; | 1353 | __be64 *lp; |
1345 | int copied = 0; | 1354 | int copied = 0; |
1346 | int error = 0; | 1355 | int error = 0; |
1347 | unsigned depth = 0; | 1356 | unsigned depth = 0; |
@@ -1365,7 +1374,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1365 | 1374 | ||
1366 | if (ht_offset_cur != ht_offset) { | 1375 | if (ht_offset_cur != ht_offset) { |
1367 | error = gfs2_dir_read_data(dip, (char *)lp, | 1376 | error = gfs2_dir_read_data(dip, (char *)lp, |
1368 | ht_offset * sizeof(u64), | 1377 | ht_offset * sizeof(__be64), |
1369 | sdp->sd_hash_bsize, 1); | 1378 | sdp->sd_hash_bsize, 1); |
1370 | if (error != sdp->sd_hash_bsize) { | 1379 | if (error != sdp->sd_hash_bsize) { |
1371 | if (error >= 0) | 1380 | if (error >= 0) |
@@ -1456,7 +1465,7 @@ out: | |||
1456 | */ | 1465 | */ |
1457 | 1466 | ||
1458 | int gfs2_dir_search(struct inode *dir, const struct qstr *name, | 1467 | int gfs2_dir_search(struct inode *dir, const struct qstr *name, |
1459 | struct gfs2_inum *inum, unsigned int *type) | 1468 | struct gfs2_inum_host *inum, unsigned int *type) |
1460 | { | 1469 | { |
1461 | struct buffer_head *bh; | 1470 | struct buffer_head *bh; |
1462 | struct gfs2_dirent *dent; | 1471 | struct gfs2_dirent *dent; |
@@ -1515,7 +1524,8 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1515 | return error; | 1524 | return error; |
1516 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1525 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1517 | ip->i_di.di_blocks++; | 1526 | ip->i_di.di_blocks++; |
1518 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 1527 | gfs2_set_inode_blocks(&ip->i_inode); |
1528 | gfs2_dinode_out(ip, bh->b_data); | ||
1519 | brelse(bh); | 1529 | brelse(bh); |
1520 | return 0; | 1530 | return 0; |
1521 | } | 1531 | } |
@@ -1531,7 +1541,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1531 | */ | 1541 | */ |
1532 | 1542 | ||
1533 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, | 1543 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, |
1534 | const struct gfs2_inum *inum, unsigned type) | 1544 | const struct gfs2_inum_host *inum, unsigned type) |
1535 | { | 1545 | { |
1536 | struct gfs2_inode *ip = GFS2_I(inode); | 1546 | struct gfs2_inode *ip = GFS2_I(inode); |
1537 | struct buffer_head *bh; | 1547 | struct buffer_head *bh; |
@@ -1558,8 +1568,8 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1558 | break; | 1568 | break; |
1559 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1569 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1560 | ip->i_di.di_entries++; | 1570 | ip->i_di.di_entries++; |
1561 | ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); | 1571 | ip->i_inode.i_mtime.tv_sec = ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1562 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 1572 | gfs2_dinode_out(ip, bh->b_data); |
1563 | brelse(bh); | 1573 | brelse(bh); |
1564 | error = 0; | 1574 | error = 0; |
1565 | break; | 1575 | break; |
@@ -1644,8 +1654,8 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1644 | gfs2_consist_inode(dip); | 1654 | gfs2_consist_inode(dip); |
1645 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1655 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1646 | dip->i_di.di_entries--; | 1656 | dip->i_di.di_entries--; |
1647 | dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); | 1657 | dip->i_inode.i_mtime.tv_sec = dip->i_inode.i_ctime.tv_sec = get_seconds(); |
1648 | gfs2_dinode_out(&dip->i_di, bh->b_data); | 1658 | gfs2_dinode_out(dip, bh->b_data); |
1649 | brelse(bh); | 1659 | brelse(bh); |
1650 | mark_inode_dirty(&dip->i_inode); | 1660 | mark_inode_dirty(&dip->i_inode); |
1651 | 1661 | ||
@@ -1666,7 +1676,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1666 | */ | 1676 | */ |
1667 | 1677 | ||
1668 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 1678 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
1669 | struct gfs2_inum *inum, unsigned int new_type) | 1679 | struct gfs2_inum_host *inum, unsigned int new_type) |
1670 | { | 1680 | { |
1671 | struct buffer_head *bh; | 1681 | struct buffer_head *bh; |
1672 | struct gfs2_dirent *dent; | 1682 | struct gfs2_dirent *dent; |
@@ -1692,8 +1702,8 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | |||
1692 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1702 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1693 | } | 1703 | } |
1694 | 1704 | ||
1695 | dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); | 1705 | dip->i_inode.i_mtime.tv_sec = dip->i_inode.i_ctime.tv_sec = get_seconds(); |
1696 | gfs2_dinode_out(&dip->i_di, bh->b_data); | 1706 | gfs2_dinode_out(dip, bh->b_data); |
1697 | brelse(bh); | 1707 | brelse(bh); |
1698 | return 0; | 1708 | return 0; |
1699 | } | 1709 | } |
@@ -1715,7 +1725,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1715 | u32 hsize, len; | 1725 | u32 hsize, len; |
1716 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | 1726 | u32 ht_offset, lp_offset, ht_offset_cur = -1; |
1717 | u32 index = 0; | 1727 | u32 index = 0; |
1718 | u64 *lp; | 1728 | __be64 *lp; |
1719 | u64 leaf_no; | 1729 | u64 leaf_no; |
1720 | int error = 0; | 1730 | int error = 0; |
1721 | 1731 | ||
@@ -1735,7 +1745,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1735 | 1745 | ||
1736 | if (ht_offset_cur != ht_offset) { | 1746 | if (ht_offset_cur != ht_offset) { |
1737 | error = gfs2_dir_read_data(dip, (char *)lp, | 1747 | error = gfs2_dir_read_data(dip, (char *)lp, |
1738 | ht_offset * sizeof(u64), | 1748 | ht_offset * sizeof(__be64), |
1739 | sdp->sd_hash_bsize, 1); | 1749 | sdp->sd_hash_bsize, 1); |
1740 | if (error != sdp->sd_hash_bsize) { | 1750 | if (error != sdp->sd_hash_bsize) { |
1741 | if (error >= 0) | 1751 | if (error >= 0) |
@@ -1859,6 +1869,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1859 | if (!dip->i_di.di_blocks) | 1869 | if (!dip->i_di.di_blocks) |
1860 | gfs2_consist_inode(dip); | 1870 | gfs2_consist_inode(dip); |
1861 | dip->i_di.di_blocks--; | 1871 | dip->i_di.di_blocks--; |
1872 | gfs2_set_inode_blocks(&dip->i_inode); | ||
1862 | } | 1873 | } |
1863 | 1874 | ||
1864 | error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size); | 1875 | error = gfs2_dir_write_data(dip, ht, index * sizeof(u64), size); |
@@ -1873,7 +1884,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1873 | goto out_end_trans; | 1884 | goto out_end_trans; |
1874 | 1885 | ||
1875 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); | 1886 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); |
1876 | gfs2_dinode_out(&dip->i_di, dibh->b_data); | 1887 | gfs2_dinode_out(dip, dibh->b_data); |
1877 | brelse(dibh); | 1888 | brelse(dibh); |
1878 | 1889 | ||
1879 | out_end_trans: | 1890 | out_end_trans: |
diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h index 371233419b07..b21b33668a5b 100644 --- a/fs/gfs2/dir.h +++ b/fs/gfs2/dir.h | |||
@@ -31,17 +31,17 @@ struct gfs2_inum; | |||
31 | typedef int (*gfs2_filldir_t) (void *opaque, | 31 | typedef int (*gfs2_filldir_t) (void *opaque, |
32 | const char *name, unsigned int length, | 32 | const char *name, unsigned int length, |
33 | u64 offset, | 33 | u64 offset, |
34 | struct gfs2_inum *inum, unsigned int type); | 34 | struct gfs2_inum_host *inum, unsigned int type); |
35 | 35 | ||
36 | int gfs2_dir_search(struct inode *dir, const struct qstr *filename, | 36 | int gfs2_dir_search(struct inode *dir, const struct qstr *filename, |
37 | struct gfs2_inum *inum, unsigned int *type); | 37 | struct gfs2_inum_host *inum, unsigned int *type); |
38 | int gfs2_dir_add(struct inode *inode, const struct qstr *filename, | 38 | int gfs2_dir_add(struct inode *inode, const struct qstr *filename, |
39 | const struct gfs2_inum *inum, unsigned int type); | 39 | const struct gfs2_inum_host *inum, unsigned int type); |
40 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); | 40 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *filename); |
41 | int gfs2_dir_read(struct inode *inode, u64 * offset, void *opaque, | 41 | int gfs2_dir_read(struct inode *inode, u64 * offset, void *opaque, |
42 | gfs2_filldir_t filldir); | 42 | gfs2_filldir_t filldir); |
43 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 43 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, |
44 | struct gfs2_inum *new_inum, unsigned int new_type); | 44 | struct gfs2_inum_host *new_inum, unsigned int new_type); |
45 | 45 | ||
46 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); | 46 | int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip); |
47 | 47 | ||
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c index 92c54e9b0dc3..cd747c00f670 100644 --- a/fs/gfs2/eaops.c +++ b/fs/gfs2/eaops.c | |||
@@ -120,7 +120,7 @@ static int system_eo_set(struct gfs2_inode *ip, struct gfs2_ea_request *er) | |||
120 | 120 | ||
121 | if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { | 121 | if (GFS2_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { |
122 | if (!(er->er_flags & GFS2_ERF_MODE)) { | 122 | if (!(er->er_flags & GFS2_ERF_MODE)) { |
123 | er->er_mode = ip->i_di.di_mode; | 123 | er->er_mode = ip->i_inode.i_mode; |
124 | er->er_flags |= GFS2_ERF_MODE; | 124 | er->er_flags |= GFS2_ERF_MODE; |
125 | } | 125 | } |
126 | error = gfs2_acl_validate_set(ip, 1, er, | 126 | error = gfs2_acl_validate_set(ip, 1, er, |
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c index a65a4ccfd4dd..ebebbdcd7057 100644 --- a/fs/gfs2/eattr.c +++ b/fs/gfs2/eattr.c | |||
@@ -112,7 +112,7 @@ fail: | |||
112 | static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | 112 | static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) |
113 | { | 113 | { |
114 | struct buffer_head *bh, *eabh; | 114 | struct buffer_head *bh, *eabh; |
115 | u64 *eablk, *end; | 115 | __be64 *eablk, *end; |
116 | int error; | 116 | int error; |
117 | 117 | ||
118 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, &bh); | 118 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, &bh); |
@@ -129,7 +129,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) | |||
129 | goto out; | 129 | goto out; |
130 | } | 130 | } |
131 | 131 | ||
132 | eablk = (u64 *)(bh->b_data + sizeof(struct gfs2_meta_header)); | 132 | eablk = (__be64 *)(bh->b_data + sizeof(struct gfs2_meta_header)); |
133 | end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs; | 133 | end = eablk + GFS2_SB(&ip->i_inode)->sd_inptrs; |
134 | 134 | ||
135 | for (; eablk < end; eablk++) { | 135 | for (; eablk < end; eablk++) { |
@@ -224,7 +224,8 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
224 | struct gfs2_rgrpd *rgd; | 224 | struct gfs2_rgrpd *rgd; |
225 | struct gfs2_holder rg_gh; | 225 | struct gfs2_holder rg_gh; |
226 | struct buffer_head *dibh; | 226 | struct buffer_head *dibh; |
227 | u64 *dataptrs, bn = 0; | 227 | __be64 *dataptrs; |
228 | u64 bn = 0; | ||
228 | u64 bstart = 0; | 229 | u64 bstart = 0; |
229 | unsigned int blen = 0; | 230 | unsigned int blen = 0; |
230 | unsigned int blks = 0; | 231 | unsigned int blks = 0; |
@@ -280,6 +281,7 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
280 | if (!ip->i_di.di_blocks) | 281 | if (!ip->i_di.di_blocks) |
281 | gfs2_consist_inode(ip); | 282 | gfs2_consist_inode(ip); |
282 | ip->i_di.di_blocks--; | 283 | ip->i_di.di_blocks--; |
284 | gfs2_set_inode_blocks(&ip->i_inode); | ||
283 | } | 285 | } |
284 | if (bstart) | 286 | if (bstart) |
285 | gfs2_free_meta(ip, bstart, blen); | 287 | gfs2_free_meta(ip, bstart, blen); |
@@ -299,9 +301,9 @@ static int ea_dealloc_unstuffed(struct gfs2_inode *ip, struct buffer_head *bh, | |||
299 | 301 | ||
300 | error = gfs2_meta_inode_buffer(ip, &dibh); | 302 | error = gfs2_meta_inode_buffer(ip, &dibh); |
301 | if (!error) { | 303 | if (!error) { |
302 | ip->i_di.di_ctime = get_seconds(); | 304 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
303 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 305 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
304 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 306 | gfs2_dinode_out(ip, dibh->b_data); |
305 | brelse(dibh); | 307 | brelse(dibh); |
306 | } | 308 | } |
307 | 309 | ||
@@ -444,7 +446,7 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
444 | struct buffer_head **bh; | 446 | struct buffer_head **bh; |
445 | unsigned int amount = GFS2_EA_DATA_LEN(ea); | 447 | unsigned int amount = GFS2_EA_DATA_LEN(ea); |
446 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); | 448 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); |
447 | u64 *dataptrs = GFS2_EA2DATAPTRS(ea); | 449 | __be64 *dataptrs = GFS2_EA2DATAPTRS(ea); |
448 | unsigned int x; | 450 | unsigned int x; |
449 | int error = 0; | 451 | int error = 0; |
450 | 452 | ||
@@ -597,6 +599,7 @@ static int ea_alloc_blk(struct gfs2_inode *ip, struct buffer_head **bhp) | |||
597 | ea->ea_num_ptrs = 0; | 599 | ea->ea_num_ptrs = 0; |
598 | 600 | ||
599 | ip->i_di.di_blocks++; | 601 | ip->i_di.di_blocks++; |
602 | gfs2_set_inode_blocks(&ip->i_inode); | ||
600 | 603 | ||
601 | return 0; | 604 | return 0; |
602 | } | 605 | } |
@@ -629,7 +632,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
629 | ea->ea_num_ptrs = 0; | 632 | ea->ea_num_ptrs = 0; |
630 | memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len); | 633 | memcpy(GFS2_EA2DATA(ea), er->er_data, er->er_data_len); |
631 | } else { | 634 | } else { |
632 | u64 *dataptr = GFS2_EA2DATAPTRS(ea); | 635 | __be64 *dataptr = GFS2_EA2DATAPTRS(ea); |
633 | const char *data = er->er_data; | 636 | const char *data = er->er_data; |
634 | unsigned int data_len = er->er_data_len; | 637 | unsigned int data_len = er->er_data_len; |
635 | unsigned int copy; | 638 | unsigned int copy; |
@@ -648,6 +651,7 @@ static int ea_write(struct gfs2_inode *ip, struct gfs2_ea_header *ea, | |||
648 | gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED); | 651 | gfs2_metatype_set(bh, GFS2_METATYPE_ED, GFS2_FORMAT_ED); |
649 | 652 | ||
650 | ip->i_di.di_blocks++; | 653 | ip->i_di.di_blocks++; |
654 | gfs2_set_inode_blocks(&ip->i_inode); | ||
651 | 655 | ||
652 | copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize : | 656 | copy = data_len > sdp->sd_jbsize ? sdp->sd_jbsize : |
653 | data_len; | 657 | data_len; |
@@ -686,7 +690,7 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
686 | if (error) | 690 | if (error) |
687 | goto out; | 691 | goto out; |
688 | 692 | ||
689 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 693 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
690 | if (error) | 694 | if (error) |
691 | goto out_gunlock_q; | 695 | goto out_gunlock_q; |
692 | 696 | ||
@@ -710,13 +714,13 @@ static int ea_alloc_skeleton(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
710 | if (!error) { | 714 | if (!error) { |
711 | if (er->er_flags & GFS2_ERF_MODE) { | 715 | if (er->er_flags & GFS2_ERF_MODE) { |
712 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), | 716 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), |
713 | (ip->i_di.di_mode & S_IFMT) == | 717 | (ip->i_inode.i_mode & S_IFMT) == |
714 | (er->er_mode & S_IFMT)); | 718 | (er->er_mode & S_IFMT)); |
715 | ip->i_di.di_mode = er->er_mode; | 719 | ip->i_inode.i_mode = er->er_mode; |
716 | } | 720 | } |
717 | ip->i_di.di_ctime = get_seconds(); | 721 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
718 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 722 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
719 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 723 | gfs2_dinode_out(ip, dibh->b_data); |
720 | brelse(dibh); | 724 | brelse(dibh); |
721 | } | 725 | } |
722 | 726 | ||
@@ -846,12 +850,12 @@ static int ea_set_simple_noalloc(struct gfs2_inode *ip, struct buffer_head *bh, | |||
846 | 850 | ||
847 | if (er->er_flags & GFS2_ERF_MODE) { | 851 | if (er->er_flags & GFS2_ERF_MODE) { |
848 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), | 852 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), |
849 | (ip->i_di.di_mode & S_IFMT) == (er->er_mode & S_IFMT)); | 853 | (ip->i_inode.i_mode & S_IFMT) == (er->er_mode & S_IFMT)); |
850 | ip->i_di.di_mode = er->er_mode; | 854 | ip->i_inode.i_mode = er->er_mode; |
851 | } | 855 | } |
852 | ip->i_di.di_ctime = get_seconds(); | 856 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
853 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 857 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
854 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 858 | gfs2_dinode_out(ip, dibh->b_data); |
855 | brelse(dibh); | 859 | brelse(dibh); |
856 | out: | 860 | out: |
857 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); | 861 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); |
@@ -931,12 +935,12 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
931 | { | 935 | { |
932 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 936 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
933 | struct buffer_head *indbh, *newbh; | 937 | struct buffer_head *indbh, *newbh; |
934 | u64 *eablk; | 938 | __be64 *eablk; |
935 | int error; | 939 | int error; |
936 | int mh_size = sizeof(struct gfs2_meta_header); | 940 | int mh_size = sizeof(struct gfs2_meta_header); |
937 | 941 | ||
938 | if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT) { | 942 | if (ip->i_di.di_flags & GFS2_DIF_EA_INDIRECT) { |
939 | u64 *end; | 943 | __be64 *end; |
940 | 944 | ||
941 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, | 945 | error = gfs2_meta_read(ip->i_gl, ip->i_di.di_eattr, DIO_WAIT, |
942 | &indbh); | 946 | &indbh); |
@@ -948,7 +952,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
948 | goto out; | 952 | goto out; |
949 | } | 953 | } |
950 | 954 | ||
951 | eablk = (u64 *)(indbh->b_data + mh_size); | 955 | eablk = (__be64 *)(indbh->b_data + mh_size); |
952 | end = eablk + sdp->sd_inptrs; | 956 | end = eablk + sdp->sd_inptrs; |
953 | 957 | ||
954 | for (; eablk < end; eablk++) | 958 | for (; eablk < end; eablk++) |
@@ -971,11 +975,12 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, | |||
971 | gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); | 975 | gfs2_metatype_set(indbh, GFS2_METATYPE_IN, GFS2_FORMAT_IN); |
972 | gfs2_buffer_clear_tail(indbh, mh_size); | 976 | gfs2_buffer_clear_tail(indbh, mh_size); |
973 | 977 | ||
974 | eablk = (u64 *)(indbh->b_data + mh_size); | 978 | eablk = (__be64 *)(indbh->b_data + mh_size); |
975 | *eablk = cpu_to_be64(ip->i_di.di_eattr); | 979 | *eablk = cpu_to_be64(ip->i_di.di_eattr); |
976 | ip->i_di.di_eattr = blk; | 980 | ip->i_di.di_eattr = blk; |
977 | ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT; | 981 | ip->i_di.di_flags |= GFS2_DIF_EA_INDIRECT; |
978 | ip->i_di.di_blocks++; | 982 | ip->i_di.di_blocks++; |
983 | gfs2_set_inode_blocks(&ip->i_inode); | ||
979 | 984 | ||
980 | eablk++; | 985 | eablk++; |
981 | } | 986 | } |
@@ -1129,9 +1134,9 @@ static int ea_remove_stuffed(struct gfs2_inode *ip, struct gfs2_ea_location *el) | |||
1129 | 1134 | ||
1130 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1135 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1131 | if (!error) { | 1136 | if (!error) { |
1132 | ip->i_di.di_ctime = get_seconds(); | 1137 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
1133 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1138 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1134 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1139 | gfs2_dinode_out(ip, dibh->b_data); |
1135 | brelse(dibh); | 1140 | brelse(dibh); |
1136 | } | 1141 | } |
1137 | 1142 | ||
@@ -1202,7 +1207,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip, | |||
1202 | struct buffer_head **bh; | 1207 | struct buffer_head **bh; |
1203 | unsigned int amount = GFS2_EA_DATA_LEN(ea); | 1208 | unsigned int amount = GFS2_EA_DATA_LEN(ea); |
1204 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); | 1209 | unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize); |
1205 | u64 *dataptrs = GFS2_EA2DATAPTRS(ea); | 1210 | __be64 *dataptrs = GFS2_EA2DATAPTRS(ea); |
1206 | unsigned int x; | 1211 | unsigned int x; |
1207 | int error; | 1212 | int error; |
1208 | 1213 | ||
@@ -1284,9 +1289,8 @@ int gfs2_ea_acl_chmod(struct gfs2_inode *ip, struct gfs2_ea_location *el, | |||
1284 | if (!error) { | 1289 | if (!error) { |
1285 | error = inode_setattr(&ip->i_inode, attr); | 1290 | error = inode_setattr(&ip->i_inode, attr); |
1286 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1291 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1287 | gfs2_inode_attr_out(ip); | ||
1288 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1292 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1289 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1293 | gfs2_dinode_out(ip, dibh->b_data); |
1290 | brelse(dibh); | 1294 | brelse(dibh); |
1291 | } | 1295 | } |
1292 | 1296 | ||
@@ -1300,7 +1304,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1300 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 1304 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
1301 | struct gfs2_rgrp_list rlist; | 1305 | struct gfs2_rgrp_list rlist; |
1302 | struct buffer_head *indbh, *dibh; | 1306 | struct buffer_head *indbh, *dibh; |
1303 | u64 *eablk, *end; | 1307 | __be64 *eablk, *end; |
1304 | unsigned int rg_blocks = 0; | 1308 | unsigned int rg_blocks = 0; |
1305 | u64 bstart = 0; | 1309 | u64 bstart = 0; |
1306 | unsigned int blen = 0; | 1310 | unsigned int blen = 0; |
@@ -1319,7 +1323,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1319 | goto out; | 1323 | goto out; |
1320 | } | 1324 | } |
1321 | 1325 | ||
1322 | eablk = (u64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); | 1326 | eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); |
1323 | end = eablk + sdp->sd_inptrs; | 1327 | end = eablk + sdp->sd_inptrs; |
1324 | 1328 | ||
1325 | for (; eablk < end; eablk++) { | 1329 | for (; eablk < end; eablk++) { |
@@ -1363,7 +1367,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1363 | 1367 | ||
1364 | gfs2_trans_add_bh(ip->i_gl, indbh, 1); | 1368 | gfs2_trans_add_bh(ip->i_gl, indbh, 1); |
1365 | 1369 | ||
1366 | eablk = (u64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); | 1370 | eablk = (__be64 *)(indbh->b_data + sizeof(struct gfs2_meta_header)); |
1367 | bstart = 0; | 1371 | bstart = 0; |
1368 | blen = 0; | 1372 | blen = 0; |
1369 | 1373 | ||
@@ -1387,6 +1391,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1387 | if (!ip->i_di.di_blocks) | 1391 | if (!ip->i_di.di_blocks) |
1388 | gfs2_consist_inode(ip); | 1392 | gfs2_consist_inode(ip); |
1389 | ip->i_di.di_blocks--; | 1393 | ip->i_di.di_blocks--; |
1394 | gfs2_set_inode_blocks(&ip->i_inode); | ||
1390 | } | 1395 | } |
1391 | if (bstart) | 1396 | if (bstart) |
1392 | gfs2_free_meta(ip, bstart, blen); | 1397 | gfs2_free_meta(ip, bstart, blen); |
@@ -1396,7 +1401,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) | |||
1396 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1401 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1397 | if (!error) { | 1402 | if (!error) { |
1398 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1403 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1399 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1404 | gfs2_dinode_out(ip, dibh->b_data); |
1400 | brelse(dibh); | 1405 | brelse(dibh); |
1401 | } | 1406 | } |
1402 | 1407 | ||
@@ -1441,11 +1446,12 @@ static int ea_dealloc_block(struct gfs2_inode *ip) | |||
1441 | if (!ip->i_di.di_blocks) | 1446 | if (!ip->i_di.di_blocks) |
1442 | gfs2_consist_inode(ip); | 1447 | gfs2_consist_inode(ip); |
1443 | ip->i_di.di_blocks--; | 1448 | ip->i_di.di_blocks--; |
1449 | gfs2_set_inode_blocks(&ip->i_inode); | ||
1444 | 1450 | ||
1445 | error = gfs2_meta_inode_buffer(ip, &dibh); | 1451 | error = gfs2_meta_inode_buffer(ip, &dibh); |
1446 | if (!error) { | 1452 | if (!error) { |
1447 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1453 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1448 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1454 | gfs2_dinode_out(ip, dibh->b_data); |
1449 | brelse(dibh); | 1455 | brelse(dibh); |
1450 | } | 1456 | } |
1451 | 1457 | ||
diff --git a/fs/gfs2/eattr.h b/fs/gfs2/eattr.h index ffa65947d686..c82dbe01d713 100644 --- a/fs/gfs2/eattr.h +++ b/fs/gfs2/eattr.h | |||
@@ -19,7 +19,7 @@ struct iattr; | |||
19 | #define GFS2_EA_SIZE(ea) \ | 19 | #define GFS2_EA_SIZE(ea) \ |
20 | ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \ | 20 | ALIGN(sizeof(struct gfs2_ea_header) + (ea)->ea_name_len + \ |
21 | ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ | 21 | ((GFS2_EA_IS_STUFFED(ea)) ? GFS2_EA_DATA_LEN(ea) : \ |
22 | (sizeof(u64) * (ea)->ea_num_ptrs)), 8) | 22 | (sizeof(__be64) * (ea)->ea_num_ptrs)), 8) |
23 | 23 | ||
24 | #define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) | 24 | #define GFS2_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) |
25 | #define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) | 25 | #define GFS2_EA_IS_LAST(ea) ((ea)->ea_flags & GFS2_EAFLAG_LAST) |
@@ -29,13 +29,13 @@ ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + (er)->er_data_len, 8) | |||
29 | 29 | ||
30 | #define GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er) \ | 30 | #define GFS2_EAREQ_SIZE_UNSTUFFED(sdp, er) \ |
31 | ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \ | 31 | ALIGN(sizeof(struct gfs2_ea_header) + (er)->er_name_len + \ |
32 | sizeof(u64) * DIV_ROUND_UP((er)->er_data_len, (sdp)->sd_jbsize), 8) | 32 | sizeof(__be64) * DIV_ROUND_UP((er)->er_data_len, (sdp)->sd_jbsize), 8) |
33 | 33 | ||
34 | #define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1)) | 34 | #define GFS2_EA2NAME(ea) ((char *)((struct gfs2_ea_header *)(ea) + 1)) |
35 | #define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len) | 35 | #define GFS2_EA2DATA(ea) (GFS2_EA2NAME(ea) + (ea)->ea_name_len) |
36 | 36 | ||
37 | #define GFS2_EA2DATAPTRS(ea) \ | 37 | #define GFS2_EA2DATAPTRS(ea) \ |
38 | ((u64 *)(GFS2_EA2NAME(ea) + ALIGN((ea)->ea_name_len, 8))) | 38 | ((__be64 *)(GFS2_EA2NAME(ea) + ALIGN((ea)->ea_name_len, 8))) |
39 | 39 | ||
40 | #define GFS2_EA2NEXT(ea) \ | 40 | #define GFS2_EA2NEXT(ea) \ |
41 | ((struct gfs2_ea_header *)((char *)(ea) + GFS2_EA_REC_LEN(ea))) | 41 | ((struct gfs2_ea_header *)((char *)(ea) + GFS2_EA_REC_LEN(ea))) |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 78fe0fae23ff..438146904b58 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | struct greedy { | 36 | struct greedy { |
37 | struct gfs2_holder gr_gh; | 37 | struct gfs2_holder gr_gh; |
38 | struct work_struct gr_work; | 38 | struct delayed_work gr_work; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | struct gfs2_gl_hash_bucket { | 41 | struct gfs2_gl_hash_bucket { |
@@ -96,7 +96,7 @@ static inline rwlock_t *gl_lock_addr(unsigned int x) | |||
96 | return &gl_hash_locks[x & (GL_HASH_LOCK_SZ-1)]; | 96 | return &gl_hash_locks[x & (GL_HASH_LOCK_SZ-1)]; |
97 | } | 97 | } |
98 | #else /* not SMP, so no spinlocks required */ | 98 | #else /* not SMP, so no spinlocks required */ |
99 | static inline rwlock_t *gl_lock_addr(x) | 99 | static inline rwlock_t *gl_lock_addr(unsigned int x) |
100 | { | 100 | { |
101 | return NULL; | 101 | return NULL; |
102 | } | 102 | } |
@@ -769,7 +769,7 @@ restart: | |||
769 | } else { | 769 | } else { |
770 | spin_unlock(&gl->gl_spin); | 770 | spin_unlock(&gl->gl_spin); |
771 | 771 | ||
772 | new_gh = gfs2_holder_get(gl, state, LM_FLAG_TRY, GFP_KERNEL); | 772 | new_gh = gfs2_holder_get(gl, state, LM_FLAG_TRY, GFP_NOFS); |
773 | if (!new_gh) | 773 | if (!new_gh) |
774 | return; | 774 | return; |
775 | set_bit(HIF_DEMOTE, &new_gh->gh_iflags); | 775 | set_bit(HIF_DEMOTE, &new_gh->gh_iflags); |
@@ -785,21 +785,6 @@ out: | |||
785 | gfs2_holder_put(new_gh); | 785 | gfs2_holder_put(new_gh); |
786 | } | 786 | } |
787 | 787 | ||
788 | void gfs2_glock_inode_squish(struct inode *inode) | ||
789 | { | ||
790 | struct gfs2_holder gh; | ||
791 | struct gfs2_glock *gl = GFS2_I(inode)->i_gl; | ||
792 | gfs2_holder_init(gl, LM_ST_UNLOCKED, 0, &gh); | ||
793 | set_bit(HIF_DEMOTE, &gh.gh_iflags); | ||
794 | spin_lock(&gl->gl_spin); | ||
795 | gfs2_assert(inode->i_sb->s_fs_info, list_empty(&gl->gl_holders)); | ||
796 | list_add_tail(&gh.gh_list, &gl->gl_waiters2); | ||
797 | run_queue(gl); | ||
798 | spin_unlock(&gl->gl_spin); | ||
799 | wait_for_completion(&gh.gh_wait); | ||
800 | gfs2_holder_uninit(&gh); | ||
801 | } | ||
802 | |||
803 | /** | 788 | /** |
804 | * state_change - record that the glock is now in a different state | 789 | * state_change - record that the glock is now in a different state |
805 | * @gl: the glock | 790 | * @gl: the glock |
@@ -847,12 +832,12 @@ static void xmote_bh(struct gfs2_glock *gl, unsigned int ret) | |||
847 | 832 | ||
848 | if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { | 833 | if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { |
849 | if (glops->go_inval) | 834 | if (glops->go_inval) |
850 | glops->go_inval(gl, DIO_METADATA | DIO_DATA); | 835 | glops->go_inval(gl, DIO_METADATA); |
851 | } else if (gl->gl_state == LM_ST_DEFERRED) { | 836 | } else if (gl->gl_state == LM_ST_DEFERRED) { |
852 | /* We might not want to do this here. | 837 | /* We might not want to do this here. |
853 | Look at moving to the inode glops. */ | 838 | Look at moving to the inode glops. */ |
854 | if (glops->go_inval) | 839 | if (glops->go_inval) |
855 | glops->go_inval(gl, DIO_DATA); | 840 | glops->go_inval(gl, 0); |
856 | } | 841 | } |
857 | 842 | ||
858 | /* Deal with each possible exit condition */ | 843 | /* Deal with each possible exit condition */ |
@@ -954,7 +939,7 @@ void gfs2_glock_xmote_th(struct gfs2_glock *gl, unsigned int state, int flags) | |||
954 | gfs2_assert_warn(sdp, state != gl->gl_state); | 939 | gfs2_assert_warn(sdp, state != gl->gl_state); |
955 | 940 | ||
956 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) | 941 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) |
957 | glops->go_sync(gl, DIO_METADATA | DIO_DATA | DIO_RELEASE); | 942 | glops->go_sync(gl); |
958 | 943 | ||
959 | gfs2_glock_hold(gl); | 944 | gfs2_glock_hold(gl); |
960 | gl->gl_req_bh = xmote_bh; | 945 | gl->gl_req_bh = xmote_bh; |
@@ -995,7 +980,7 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
995 | state_change(gl, LM_ST_UNLOCKED); | 980 | state_change(gl, LM_ST_UNLOCKED); |
996 | 981 | ||
997 | if (glops->go_inval) | 982 | if (glops->go_inval) |
998 | glops->go_inval(gl, DIO_METADATA | DIO_DATA); | 983 | glops->go_inval(gl, DIO_METADATA); |
999 | 984 | ||
1000 | if (gh) { | 985 | if (gh) { |
1001 | spin_lock(&gl->gl_spin); | 986 | spin_lock(&gl->gl_spin); |
@@ -1041,7 +1026,7 @@ void gfs2_glock_drop_th(struct gfs2_glock *gl) | |||
1041 | gfs2_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); | 1026 | gfs2_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); |
1042 | 1027 | ||
1043 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) | 1028 | if (gl->gl_state == LM_ST_EXCLUSIVE && glops->go_sync) |
1044 | glops->go_sync(gl, DIO_METADATA | DIO_DATA | DIO_RELEASE); | 1029 | glops->go_sync(gl); |
1045 | 1030 | ||
1046 | gfs2_glock_hold(gl); | 1031 | gfs2_glock_hold(gl); |
1047 | gl->gl_req_bh = drop_bh; | 1032 | gl->gl_req_bh = drop_bh; |
@@ -1244,9 +1229,6 @@ restart: | |||
1244 | 1229 | ||
1245 | clear_bit(GLF_PREFETCH, &gl->gl_flags); | 1230 | clear_bit(GLF_PREFETCH, &gl->gl_flags); |
1246 | 1231 | ||
1247 | if (error == GLR_TRYFAILED && (gh->gh_flags & GL_DUMP)) | ||
1248 | dump_glock(gl); | ||
1249 | |||
1250 | return error; | 1232 | return error; |
1251 | } | 1233 | } |
1252 | 1234 | ||
@@ -1368,9 +1350,9 @@ static void gfs2_glock_prefetch(struct gfs2_glock *gl, unsigned int state, | |||
1368 | glops->go_xmote_th(gl, state, flags); | 1350 | glops->go_xmote_th(gl, state, flags); |
1369 | } | 1351 | } |
1370 | 1352 | ||
1371 | static void greedy_work(void *data) | 1353 | static void greedy_work(struct work_struct *work) |
1372 | { | 1354 | { |
1373 | struct greedy *gr = data; | 1355 | struct greedy *gr = container_of(work, struct greedy, gr_work.work); |
1374 | struct gfs2_holder *gh = &gr->gr_gh; | 1356 | struct gfs2_holder *gh = &gr->gr_gh; |
1375 | struct gfs2_glock *gl = gh->gh_gl; | 1357 | struct gfs2_glock *gl = gh->gh_gl; |
1376 | const struct gfs2_glock_operations *glops = gl->gl_ops; | 1358 | const struct gfs2_glock_operations *glops = gl->gl_ops; |
@@ -1422,7 +1404,7 @@ int gfs2_glock_be_greedy(struct gfs2_glock *gl, unsigned int time) | |||
1422 | 1404 | ||
1423 | gfs2_holder_init(gl, 0, 0, gh); | 1405 | gfs2_holder_init(gl, 0, 0, gh); |
1424 | set_bit(HIF_GREEDY, &gh->gh_iflags); | 1406 | set_bit(HIF_GREEDY, &gh->gh_iflags); |
1425 | INIT_WORK(&gr->gr_work, greedy_work, gr); | 1407 | INIT_DELAYED_WORK(&gr->gr_work, greedy_work); |
1426 | 1408 | ||
1427 | set_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); | 1409 | set_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); |
1428 | schedule_delayed_work(&gr->gr_work, time); | 1410 | schedule_delayed_work(&gr->gr_work, time); |
@@ -1923,7 +1905,7 @@ out: | |||
1923 | 1905 | ||
1924 | static void scan_glock(struct gfs2_glock *gl) | 1906 | static void scan_glock(struct gfs2_glock *gl) |
1925 | { | 1907 | { |
1926 | if (gl->gl_ops == &gfs2_inode_glops) | 1908 | if (gl->gl_ops == &gfs2_inode_glops && gl->gl_object) |
1927 | return; | 1909 | return; |
1928 | 1910 | ||
1929 | if (gfs2_glmutex_trylock(gl)) { | 1911 | if (gfs2_glmutex_trylock(gl)) { |
@@ -2078,7 +2060,7 @@ static int dump_inode(struct gfs2_inode *ip) | |||
2078 | printk(KERN_INFO " num = %llu %llu\n", | 2060 | printk(KERN_INFO " num = %llu %llu\n", |
2079 | (unsigned long long)ip->i_num.no_formal_ino, | 2061 | (unsigned long long)ip->i_num.no_formal_ino, |
2080 | (unsigned long long)ip->i_num.no_addr); | 2062 | (unsigned long long)ip->i_num.no_addr); |
2081 | printk(KERN_INFO " type = %u\n", IF2DT(ip->i_di.di_mode)); | 2063 | printk(KERN_INFO " type = %u\n", IF2DT(ip->i_inode.i_mode)); |
2082 | printk(KERN_INFO " i_flags ="); | 2064 | printk(KERN_INFO " i_flags ="); |
2083 | for (x = 0; x < 32; x++) | 2065 | for (x = 0; x < 32; x++) |
2084 | if (test_bit(x, &ip->i_flags)) | 2066 | if (test_bit(x, &ip->i_flags)) |
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h index 2b2a889ee2cc..fb39108fc05c 100644 --- a/fs/gfs2/glock.h +++ b/fs/gfs2/glock.h | |||
@@ -27,8 +27,6 @@ | |||
27 | #define GL_ATIME 0x00000200 | 27 | #define GL_ATIME 0x00000200 |
28 | #define GL_NOCACHE 0x00000400 | 28 | #define GL_NOCACHE 0x00000400 |
29 | #define GL_NOCANCEL 0x00001000 | 29 | #define GL_NOCANCEL 0x00001000 |
30 | #define GL_AOP 0x00004000 | ||
31 | #define GL_DUMP 0x00008000 | ||
32 | 30 | ||
33 | #define GLR_TRYFAILED 13 | 31 | #define GLR_TRYFAILED 13 |
34 | #define GLR_CANCELED 14 | 32 | #define GLR_CANCELED 14 |
@@ -108,7 +106,6 @@ void gfs2_glock_dq_uninit_m(unsigned int num_gh, struct gfs2_holder *ghs); | |||
108 | void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, u64 number, | 106 | void gfs2_glock_prefetch_num(struct gfs2_sbd *sdp, u64 number, |
109 | const struct gfs2_glock_operations *glops, | 107 | const struct gfs2_glock_operations *glops, |
110 | unsigned int state, int flags); | 108 | unsigned int state, int flags); |
111 | void gfs2_glock_inode_squish(struct inode *inode); | ||
112 | 109 | ||
113 | /** | 110 | /** |
114 | * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock | 111 | * gfs2_glock_nq_init - intialize a holder and enqueue it on a glock |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 41a6b6818a50..b068d10bcb6e 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -92,7 +92,7 @@ static void gfs2_pte_inval(struct gfs2_glock *gl) | |||
92 | 92 | ||
93 | ip = gl->gl_object; | 93 | ip = gl->gl_object; |
94 | inode = &ip->i_inode; | 94 | inode = &ip->i_inode; |
95 | if (!ip || !S_ISREG(ip->i_di.di_mode)) | 95 | if (!ip || !S_ISREG(inode->i_mode)) |
96 | return; | 96 | return; |
97 | 97 | ||
98 | if (!test_bit(GIF_PAGED, &ip->i_flags)) | 98 | if (!test_bit(GIF_PAGED, &ip->i_flags)) |
@@ -107,89 +107,20 @@ static void gfs2_pte_inval(struct gfs2_glock *gl) | |||
107 | } | 107 | } |
108 | 108 | ||
109 | /** | 109 | /** |
110 | * gfs2_page_inval - Invalidate all pages associated with a glock | ||
111 | * @gl: the glock | ||
112 | * | ||
113 | */ | ||
114 | |||
115 | static void gfs2_page_inval(struct gfs2_glock *gl) | ||
116 | { | ||
117 | struct gfs2_inode *ip; | ||
118 | struct inode *inode; | ||
119 | |||
120 | ip = gl->gl_object; | ||
121 | inode = &ip->i_inode; | ||
122 | if (!ip || !S_ISREG(ip->i_di.di_mode)) | ||
123 | return; | ||
124 | |||
125 | truncate_inode_pages(inode->i_mapping, 0); | ||
126 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !inode->i_mapping->nrpages); | ||
127 | clear_bit(GIF_PAGED, &ip->i_flags); | ||
128 | } | ||
129 | |||
130 | /** | ||
131 | * gfs2_page_wait - Wait for writeback of data | ||
132 | * @gl: the glock | ||
133 | * | ||
134 | * Syncs data (not metadata) for a regular file. | ||
135 | * No-op for all other types. | ||
136 | */ | ||
137 | |||
138 | static void gfs2_page_wait(struct gfs2_glock *gl) | ||
139 | { | ||
140 | struct gfs2_inode *ip = gl->gl_object; | ||
141 | struct inode *inode = &ip->i_inode; | ||
142 | struct address_space *mapping = inode->i_mapping; | ||
143 | int error; | ||
144 | |||
145 | if (!S_ISREG(ip->i_di.di_mode)) | ||
146 | return; | ||
147 | |||
148 | error = filemap_fdatawait(mapping); | ||
149 | |||
150 | /* Put back any errors cleared by filemap_fdatawait() | ||
151 | so they can be caught by someone who can pass them | ||
152 | up to user space. */ | ||
153 | |||
154 | if (error == -ENOSPC) | ||
155 | set_bit(AS_ENOSPC, &mapping->flags); | ||
156 | else if (error) | ||
157 | set_bit(AS_EIO, &mapping->flags); | ||
158 | |||
159 | } | ||
160 | |||
161 | static void gfs2_page_writeback(struct gfs2_glock *gl) | ||
162 | { | ||
163 | struct gfs2_inode *ip = gl->gl_object; | ||
164 | struct inode *inode = &ip->i_inode; | ||
165 | struct address_space *mapping = inode->i_mapping; | ||
166 | |||
167 | if (!S_ISREG(ip->i_di.di_mode)) | ||
168 | return; | ||
169 | |||
170 | filemap_fdatawrite(mapping); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * meta_go_sync - sync out the metadata for this glock | 110 | * meta_go_sync - sync out the metadata for this glock |
175 | * @gl: the glock | 111 | * @gl: the glock |
176 | * @flags: DIO_* | ||
177 | * | 112 | * |
178 | * Called when demoting or unlocking an EX glock. We must flush | 113 | * Called when demoting or unlocking an EX glock. We must flush |
179 | * to disk all dirty buffers/pages relating to this glock, and must not | 114 | * to disk all dirty buffers/pages relating to this glock, and must not |
180 | * not return to caller to demote/unlock the glock until I/O is complete. | 115 | * not return to caller to demote/unlock the glock until I/O is complete. |
181 | */ | 116 | */ |
182 | 117 | ||
183 | static void meta_go_sync(struct gfs2_glock *gl, int flags) | 118 | static void meta_go_sync(struct gfs2_glock *gl) |
184 | { | 119 | { |
185 | if (!(flags & DIO_METADATA)) | ||
186 | return; | ||
187 | |||
188 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { | 120 | if (test_and_clear_bit(GLF_DIRTY, &gl->gl_flags)) { |
189 | gfs2_log_flush(gl->gl_sbd, gl); | 121 | gfs2_log_flush(gl->gl_sbd, gl); |
190 | gfs2_meta_sync(gl); | 122 | gfs2_meta_sync(gl); |
191 | if (flags & DIO_RELEASE) | 123 | gfs2_ail_empty_gl(gl); |
192 | gfs2_ail_empty_gl(gl); | ||
193 | } | 124 | } |
194 | 125 | ||
195 | } | 126 | } |
@@ -264,31 +195,31 @@ static void inode_go_drop_th(struct gfs2_glock *gl) | |||
264 | /** | 195 | /** |
265 | * inode_go_sync - Sync the dirty data and/or metadata for an inode glock | 196 | * inode_go_sync - Sync the dirty data and/or metadata for an inode glock |
266 | * @gl: the glock protecting the inode | 197 | * @gl: the glock protecting the inode |
267 | * @flags: | ||
268 | * | 198 | * |
269 | */ | 199 | */ |
270 | 200 | ||
271 | static void inode_go_sync(struct gfs2_glock *gl, int flags) | 201 | static void inode_go_sync(struct gfs2_glock *gl) |
272 | { | 202 | { |
273 | int meta = (flags & DIO_METADATA); | 203 | struct gfs2_inode *ip = gl->gl_object; |
274 | int data = (flags & DIO_DATA); | 204 | |
205 | if (ip && !S_ISREG(ip->i_inode.i_mode)) | ||
206 | ip = NULL; | ||
275 | 207 | ||
276 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { | 208 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) { |
277 | if (meta && data) { | 209 | gfs2_log_flush(gl->gl_sbd, gl); |
278 | gfs2_page_writeback(gl); | 210 | if (ip) |
279 | gfs2_log_flush(gl->gl_sbd, gl); | 211 | filemap_fdatawrite(ip->i_inode.i_mapping); |
280 | gfs2_meta_sync(gl); | 212 | gfs2_meta_sync(gl); |
281 | gfs2_page_wait(gl); | 213 | if (ip) { |
282 | clear_bit(GLF_DIRTY, &gl->gl_flags); | 214 | struct address_space *mapping = ip->i_inode.i_mapping; |
283 | } else if (meta) { | 215 | int error = filemap_fdatawait(mapping); |
284 | gfs2_log_flush(gl->gl_sbd, gl); | 216 | if (error == -ENOSPC) |
285 | gfs2_meta_sync(gl); | 217 | set_bit(AS_ENOSPC, &mapping->flags); |
286 | } else if (data) { | 218 | else if (error) |
287 | gfs2_page_writeback(gl); | 219 | set_bit(AS_EIO, &mapping->flags); |
288 | gfs2_page_wait(gl); | ||
289 | } | 220 | } |
290 | if (flags & DIO_RELEASE) | 221 | clear_bit(GLF_DIRTY, &gl->gl_flags); |
291 | gfs2_ail_empty_gl(gl); | 222 | gfs2_ail_empty_gl(gl); |
292 | } | 223 | } |
293 | } | 224 | } |
294 | 225 | ||
@@ -301,15 +232,20 @@ static void inode_go_sync(struct gfs2_glock *gl, int flags) | |||
301 | 232 | ||
302 | static void inode_go_inval(struct gfs2_glock *gl, int flags) | 233 | static void inode_go_inval(struct gfs2_glock *gl, int flags) |
303 | { | 234 | { |
235 | struct gfs2_inode *ip = gl->gl_object; | ||
304 | int meta = (flags & DIO_METADATA); | 236 | int meta = (flags & DIO_METADATA); |
305 | int data = (flags & DIO_DATA); | ||
306 | 237 | ||
307 | if (meta) { | 238 | if (meta) { |
308 | gfs2_meta_inval(gl); | 239 | gfs2_meta_inval(gl); |
309 | gl->gl_vn++; | 240 | if (ip) |
241 | set_bit(GIF_INVALID, &ip->i_flags); | ||
242 | } | ||
243 | |||
244 | if (ip && S_ISREG(ip->i_inode.i_mode)) { | ||
245 | truncate_inode_pages(ip->i_inode.i_mapping, 0); | ||
246 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !ip->i_inode.i_mapping->nrpages); | ||
247 | clear_bit(GIF_PAGED, &ip->i_flags); | ||
310 | } | 248 | } |
311 | if (data) | ||
312 | gfs2_page_inval(gl); | ||
313 | } | 249 | } |
314 | 250 | ||
315 | /** | 251 | /** |
@@ -351,11 +287,10 @@ static int inode_go_lock(struct gfs2_holder *gh) | |||
351 | if (!ip) | 287 | if (!ip) |
352 | return 0; | 288 | return 0; |
353 | 289 | ||
354 | if (ip->i_vn != gl->gl_vn) { | 290 | if (test_bit(GIF_INVALID, &ip->i_flags)) { |
355 | error = gfs2_inode_refresh(ip); | 291 | error = gfs2_inode_refresh(ip); |
356 | if (error) | 292 | if (error) |
357 | return error; | 293 | return error; |
358 | gfs2_inode_attr_in(ip); | ||
359 | } | 294 | } |
360 | 295 | ||
361 | if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) && | 296 | if ((ip->i_di.di_flags & GFS2_DIF_TRUNC_IN_PROG) && |
@@ -379,11 +314,8 @@ static void inode_go_unlock(struct gfs2_holder *gh) | |||
379 | struct gfs2_glock *gl = gh->gh_gl; | 314 | struct gfs2_glock *gl = gh->gh_gl; |
380 | struct gfs2_inode *ip = gl->gl_object; | 315 | struct gfs2_inode *ip = gl->gl_object; |
381 | 316 | ||
382 | if (ip == NULL) | 317 | if (ip) |
383 | return; | 318 | gfs2_meta_cache_flush(ip); |
384 | if (test_bit(GLF_DIRTY, &gl->gl_flags)) | ||
385 | gfs2_inode_attr_in(ip); | ||
386 | gfs2_meta_cache_flush(ip); | ||
387 | } | 319 | } |
388 | 320 | ||
389 | /** | 321 | /** |
@@ -491,13 +423,13 @@ static void trans_go_xmote_bh(struct gfs2_glock *gl) | |||
491 | struct gfs2_sbd *sdp = gl->gl_sbd; | 423 | struct gfs2_sbd *sdp = gl->gl_sbd; |
492 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 424 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
493 | struct gfs2_glock *j_gl = ip->i_gl; | 425 | struct gfs2_glock *j_gl = ip->i_gl; |
494 | struct gfs2_log_header head; | 426 | struct gfs2_log_header_host head; |
495 | int error; | 427 | int error; |
496 | 428 | ||
497 | if (gl->gl_state != LM_ST_UNLOCKED && | 429 | if (gl->gl_state != LM_ST_UNLOCKED && |
498 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { | 430 | test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { |
499 | gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); | 431 | gfs2_meta_cache_flush(GFS2_I(sdp->sd_jdesc->jd_inode)); |
500 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); | 432 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
501 | 433 | ||
502 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 434 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
503 | if (error) | 435 | if (error) |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 118dc693d111..734421edae85 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -14,8 +14,6 @@ | |||
14 | 14 | ||
15 | #define DIO_WAIT 0x00000010 | 15 | #define DIO_WAIT 0x00000010 |
16 | #define DIO_METADATA 0x00000020 | 16 | #define DIO_METADATA 0x00000020 |
17 | #define DIO_DATA 0x00000040 | ||
18 | #define DIO_RELEASE 0x00000080 | ||
19 | #define DIO_ALL 0x00000100 | 17 | #define DIO_ALL 0x00000100 |
20 | 18 | ||
21 | struct gfs2_log_operations; | 19 | struct gfs2_log_operations; |
@@ -41,7 +39,7 @@ struct gfs2_log_operations { | |||
41 | void (*lo_before_commit) (struct gfs2_sbd *sdp); | 39 | void (*lo_before_commit) (struct gfs2_sbd *sdp); |
42 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); | 40 | void (*lo_after_commit) (struct gfs2_sbd *sdp, struct gfs2_ail *ai); |
43 | void (*lo_before_scan) (struct gfs2_jdesc *jd, | 41 | void (*lo_before_scan) (struct gfs2_jdesc *jd, |
44 | struct gfs2_log_header *head, int pass); | 42 | struct gfs2_log_header_host *head, int pass); |
45 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, | 43 | int (*lo_scan_elements) (struct gfs2_jdesc *jd, unsigned int start, |
46 | struct gfs2_log_descriptor *ld, __be64 *ptr, | 44 | struct gfs2_log_descriptor *ld, __be64 *ptr, |
47 | int pass); | 45 | int pass); |
@@ -67,8 +65,8 @@ struct gfs2_rgrpd { | |||
67 | struct list_head rd_list_mru; | 65 | struct list_head rd_list_mru; |
68 | struct list_head rd_recent; /* Recently used rgrps */ | 66 | struct list_head rd_recent; /* Recently used rgrps */ |
69 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ | 67 | struct gfs2_glock *rd_gl; /* Glock for this rgrp */ |
70 | struct gfs2_rindex rd_ri; | 68 | struct gfs2_rindex_host rd_ri; |
71 | struct gfs2_rgrp rd_rg; | 69 | struct gfs2_rgrp_host rd_rg; |
72 | u64 rd_rg_vn; | 70 | u64 rd_rg_vn; |
73 | struct gfs2_bitmap *rd_bits; | 71 | struct gfs2_bitmap *rd_bits; |
74 | unsigned int rd_bh_count; | 72 | unsigned int rd_bh_count; |
@@ -103,18 +101,17 @@ struct gfs2_bufdata { | |||
103 | }; | 101 | }; |
104 | 102 | ||
105 | struct gfs2_glock_operations { | 103 | struct gfs2_glock_operations { |
106 | void (*go_xmote_th) (struct gfs2_glock * gl, unsigned int state, | 104 | void (*go_xmote_th) (struct gfs2_glock *gl, unsigned int state, int flags); |
107 | int flags); | 105 | void (*go_xmote_bh) (struct gfs2_glock *gl); |
108 | void (*go_xmote_bh) (struct gfs2_glock * gl); | 106 | void (*go_drop_th) (struct gfs2_glock *gl); |
109 | void (*go_drop_th) (struct gfs2_glock * gl); | 107 | void (*go_drop_bh) (struct gfs2_glock *gl); |
110 | void (*go_drop_bh) (struct gfs2_glock * gl); | 108 | void (*go_sync) (struct gfs2_glock *gl); |
111 | void (*go_sync) (struct gfs2_glock * gl, int flags); | 109 | void (*go_inval) (struct gfs2_glock *gl, int flags); |
112 | void (*go_inval) (struct gfs2_glock * gl, int flags); | 110 | int (*go_demote_ok) (struct gfs2_glock *gl); |
113 | int (*go_demote_ok) (struct gfs2_glock * gl); | 111 | int (*go_lock) (struct gfs2_holder *gh); |
114 | int (*go_lock) (struct gfs2_holder * gh); | 112 | void (*go_unlock) (struct gfs2_holder *gh); |
115 | void (*go_unlock) (struct gfs2_holder * gh); | 113 | void (*go_callback) (struct gfs2_glock *gl, unsigned int state); |
116 | void (*go_callback) (struct gfs2_glock * gl, unsigned int state); | 114 | void (*go_greedy) (struct gfs2_glock *gl); |
117 | void (*go_greedy) (struct gfs2_glock * gl); | ||
118 | const int go_type; | 115 | const int go_type; |
119 | }; | 116 | }; |
120 | 117 | ||
@@ -217,6 +214,7 @@ struct gfs2_alloc { | |||
217 | }; | 214 | }; |
218 | 215 | ||
219 | enum { | 216 | enum { |
217 | GIF_INVALID = 0, | ||
220 | GIF_QD_LOCKED = 1, | 218 | GIF_QD_LOCKED = 1, |
221 | GIF_PAGED = 2, | 219 | GIF_PAGED = 2, |
222 | GIF_SW_PAGED = 3, | 220 | GIF_SW_PAGED = 3, |
@@ -224,12 +222,11 @@ enum { | |||
224 | 222 | ||
225 | struct gfs2_inode { | 223 | struct gfs2_inode { |
226 | struct inode i_inode; | 224 | struct inode i_inode; |
227 | struct gfs2_inum i_num; | 225 | struct gfs2_inum_host i_num; |
228 | 226 | ||
229 | unsigned long i_flags; /* GIF_... */ | 227 | unsigned long i_flags; /* GIF_... */ |
230 | 228 | ||
231 | u64 i_vn; | 229 | struct gfs2_dinode_host i_di; /* To be replaced by ref to block */ |
232 | struct gfs2_dinode i_di; /* To be replaced by ref to block */ | ||
233 | 230 | ||
234 | struct gfs2_glock *i_gl; /* Move into i_gh? */ | 231 | struct gfs2_glock *i_gl; /* Move into i_gh? */ |
235 | struct gfs2_holder i_iopen_gh; | 232 | struct gfs2_holder i_iopen_gh; |
@@ -450,7 +447,7 @@ struct gfs2_sbd { | |||
450 | struct super_block *sd_vfs_meta; | 447 | struct super_block *sd_vfs_meta; |
451 | struct kobject sd_kobj; | 448 | struct kobject sd_kobj; |
452 | unsigned long sd_flags; /* SDF_... */ | 449 | unsigned long sd_flags; /* SDF_... */ |
453 | struct gfs2_sb sd_sb; | 450 | struct gfs2_sb_host sd_sb; |
454 | 451 | ||
455 | /* Constants computed on mount */ | 452 | /* Constants computed on mount */ |
456 | 453 | ||
@@ -503,8 +500,8 @@ struct gfs2_sbd { | |||
503 | 500 | ||
504 | spinlock_t sd_statfs_spin; | 501 | spinlock_t sd_statfs_spin; |
505 | struct mutex sd_statfs_mutex; | 502 | struct mutex sd_statfs_mutex; |
506 | struct gfs2_statfs_change sd_statfs_master; | 503 | struct gfs2_statfs_change_host sd_statfs_master; |
507 | struct gfs2_statfs_change sd_statfs_local; | 504 | struct gfs2_statfs_change_host sd_statfs_local; |
508 | unsigned long sd_statfs_sync_time; | 505 | unsigned long sd_statfs_sync_time; |
509 | 506 | ||
510 | /* Resource group stuff */ | 507 | /* Resource group stuff */ |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 57c43ac47925..d122074c45e1 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -38,83 +38,12 @@ | |||
38 | #include "trans.h" | 38 | #include "trans.h" |
39 | #include "util.h" | 39 | #include "util.h" |
40 | 40 | ||
41 | /** | ||
42 | * gfs2_inode_attr_in - Copy attributes from the dinode into the VFS inode | ||
43 | * @ip: The GFS2 inode (with embedded disk inode data) | ||
44 | * @inode: The Linux VFS inode | ||
45 | * | ||
46 | */ | ||
47 | |||
48 | void gfs2_inode_attr_in(struct gfs2_inode *ip) | ||
49 | { | ||
50 | struct inode *inode = &ip->i_inode; | ||
51 | struct gfs2_dinode *di = &ip->i_di; | ||
52 | |||
53 | inode->i_ino = ip->i_num.no_addr; | ||
54 | |||
55 | switch (di->di_mode & S_IFMT) { | ||
56 | case S_IFBLK: | ||
57 | case S_IFCHR: | ||
58 | inode->i_rdev = MKDEV(di->di_major, di->di_minor); | ||
59 | break; | ||
60 | default: | ||
61 | inode->i_rdev = 0; | ||
62 | break; | ||
63 | }; | ||
64 | |||
65 | inode->i_mode = di->di_mode; | ||
66 | inode->i_nlink = di->di_nlink; | ||
67 | inode->i_uid = di->di_uid; | ||
68 | inode->i_gid = di->di_gid; | ||
69 | i_size_write(inode, di->di_size); | ||
70 | inode->i_atime.tv_sec = di->di_atime; | ||
71 | inode->i_mtime.tv_sec = di->di_mtime; | ||
72 | inode->i_ctime.tv_sec = di->di_ctime; | ||
73 | inode->i_atime.tv_nsec = 0; | ||
74 | inode->i_mtime.tv_nsec = 0; | ||
75 | inode->i_ctime.tv_nsec = 0; | ||
76 | inode->i_blocks = di->di_blocks << | ||
77 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | ||
78 | |||
79 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | ||
80 | inode->i_flags |= S_IMMUTABLE; | ||
81 | else | ||
82 | inode->i_flags &= ~S_IMMUTABLE; | ||
83 | |||
84 | if (di->di_flags & GFS2_DIF_APPENDONLY) | ||
85 | inode->i_flags |= S_APPEND; | ||
86 | else | ||
87 | inode->i_flags &= ~S_APPEND; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * gfs2_inode_attr_out - Copy attributes from VFS inode into the dinode | ||
92 | * @ip: The GFS2 inode | ||
93 | * | ||
94 | * Only copy out the attributes that we want the VFS layer | ||
95 | * to be able to modify. | ||
96 | */ | ||
97 | |||
98 | void gfs2_inode_attr_out(struct gfs2_inode *ip) | ||
99 | { | ||
100 | struct inode *inode = &ip->i_inode; | ||
101 | struct gfs2_dinode *di = &ip->i_di; | ||
102 | gfs2_assert_withdraw(GFS2_SB(inode), | ||
103 | (di->di_mode & S_IFMT) == (inode->i_mode & S_IFMT)); | ||
104 | di->di_mode = inode->i_mode; | ||
105 | di->di_uid = inode->i_uid; | ||
106 | di->di_gid = inode->i_gid; | ||
107 | di->di_atime = inode->i_atime.tv_sec; | ||
108 | di->di_mtime = inode->i_mtime.tv_sec; | ||
109 | di->di_ctime = inode->i_ctime.tv_sec; | ||
110 | } | ||
111 | |||
112 | static int iget_test(struct inode *inode, void *opaque) | 41 | static int iget_test(struct inode *inode, void *opaque) |
113 | { | 42 | { |
114 | struct gfs2_inode *ip = GFS2_I(inode); | 43 | struct gfs2_inode *ip = GFS2_I(inode); |
115 | struct gfs2_inum *inum = opaque; | 44 | struct gfs2_inum_host *inum = opaque; |
116 | 45 | ||
117 | if (ip && ip->i_num.no_addr == inum->no_addr) | 46 | if (ip->i_num.no_addr == inum->no_addr) |
118 | return 1; | 47 | return 1; |
119 | 48 | ||
120 | return 0; | 49 | return 0; |
@@ -123,19 +52,20 @@ static int iget_test(struct inode *inode, void *opaque) | |||
123 | static int iget_set(struct inode *inode, void *opaque) | 52 | static int iget_set(struct inode *inode, void *opaque) |
124 | { | 53 | { |
125 | struct gfs2_inode *ip = GFS2_I(inode); | 54 | struct gfs2_inode *ip = GFS2_I(inode); |
126 | struct gfs2_inum *inum = opaque; | 55 | struct gfs2_inum_host *inum = opaque; |
127 | 56 | ||
128 | ip->i_num = *inum; | 57 | ip->i_num = *inum; |
58 | inode->i_ino = inum->no_addr; | ||
129 | return 0; | 59 | return 0; |
130 | } | 60 | } |
131 | 61 | ||
132 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum) | 62 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) |
133 | { | 63 | { |
134 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, | 64 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, |
135 | iget_test, inum); | 65 | iget_test, inum); |
136 | } | 66 | } |
137 | 67 | ||
138 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | 68 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) |
139 | { | 69 | { |
140 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, | 70 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, |
141 | iget_test, iget_set, inum); | 71 | iget_test, iget_set, inum); |
@@ -150,13 +80,16 @@ static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | |||
150 | * Returns: A VFS inode, or an error | 80 | * Returns: A VFS inode, or an error |
151 | */ | 81 | */ |
152 | 82 | ||
153 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned int type) | 83 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned int type) |
154 | { | 84 | { |
155 | struct inode *inode = gfs2_iget(sb, inum); | 85 | struct inode *inode = gfs2_iget(sb, inum); |
156 | struct gfs2_inode *ip = GFS2_I(inode); | 86 | struct gfs2_inode *ip = GFS2_I(inode); |
157 | struct gfs2_glock *io_gl; | 87 | struct gfs2_glock *io_gl; |
158 | int error; | 88 | int error; |
159 | 89 | ||
90 | if (!inode) | ||
91 | return ERR_PTR(-ENOBUFS); | ||
92 | |||
160 | if (inode->i_state & I_NEW) { | 93 | if (inode->i_state & I_NEW) { |
161 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 94 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
162 | umode_t mode = DT2IF(type); | 95 | umode_t mode = DT2IF(type); |
@@ -185,7 +118,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, | |||
185 | if (unlikely(error)) | 118 | if (unlikely(error)) |
186 | goto fail_put; | 119 | goto fail_put; |
187 | 120 | ||
188 | ip->i_vn = ip->i_gl->gl_vn - 1; | 121 | set_bit(GIF_INVALID, &ip->i_flags); |
189 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); | 122 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); |
190 | if (unlikely(error)) | 123 | if (unlikely(error)) |
191 | goto fail_iopen; | 124 | goto fail_iopen; |
@@ -205,6 +138,63 @@ fail: | |||
205 | return ERR_PTR(error); | 138 | return ERR_PTR(error); |
206 | } | 139 | } |
207 | 140 | ||
141 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | ||
142 | { | ||
143 | struct gfs2_dinode_host *di = &ip->i_di; | ||
144 | const struct gfs2_dinode *str = buf; | ||
145 | |||
146 | if (ip->i_num.no_addr != be64_to_cpu(str->di_num.no_addr)) { | ||
147 | if (gfs2_consist_inode(ip)) | ||
148 | gfs2_dinode_print(ip); | ||
149 | return -EIO; | ||
150 | } | ||
151 | if (ip->i_num.no_formal_ino != be64_to_cpu(str->di_num.no_formal_ino)) | ||
152 | return -ESTALE; | ||
153 | |||
154 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | ||
155 | ip->i_inode.i_rdev = 0; | ||
156 | switch (ip->i_inode.i_mode & S_IFMT) { | ||
157 | case S_IFBLK: | ||
158 | case S_IFCHR: | ||
159 | ip->i_inode.i_rdev = MKDEV(be32_to_cpu(str->di_major), | ||
160 | be32_to_cpu(str->di_minor)); | ||
161 | break; | ||
162 | }; | ||
163 | |||
164 | ip->i_inode.i_uid = be32_to_cpu(str->di_uid); | ||
165 | ip->i_inode.i_gid = be32_to_cpu(str->di_gid); | ||
166 | /* | ||
167 | * We will need to review setting the nlink count here in the | ||
168 | * light of the forthcoming ro bind mount work. This is a reminder | ||
169 | * to do that. | ||
170 | */ | ||
171 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | ||
172 | di->di_size = be64_to_cpu(str->di_size); | ||
173 | i_size_write(&ip->i_inode, di->di_size); | ||
174 | di->di_blocks = be64_to_cpu(str->di_blocks); | ||
175 | gfs2_set_inode_blocks(&ip->i_inode); | ||
176 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); | ||
177 | ip->i_inode.i_atime.tv_nsec = 0; | ||
178 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | ||
179 | ip->i_inode.i_mtime.tv_nsec = 0; | ||
180 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | ||
181 | ip->i_inode.i_ctime.tv_nsec = 0; | ||
182 | |||
183 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | ||
184 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | ||
185 | di->di_generation = be64_to_cpu(str->di_generation); | ||
186 | |||
187 | di->di_flags = be32_to_cpu(str->di_flags); | ||
188 | gfs2_set_inode_flags(&ip->i_inode); | ||
189 | di->di_height = be16_to_cpu(str->di_height); | ||
190 | |||
191 | di->di_depth = be16_to_cpu(str->di_depth); | ||
192 | di->di_entries = be32_to_cpu(str->di_entries); | ||
193 | |||
194 | di->di_eattr = be64_to_cpu(str->di_eattr); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
208 | /** | 198 | /** |
209 | * gfs2_inode_refresh - Refresh the incore copy of the dinode | 199 | * gfs2_inode_refresh - Refresh the incore copy of the dinode |
210 | * @ip: The GFS2 inode | 200 | * @ip: The GFS2 inode |
@@ -226,21 +216,11 @@ int gfs2_inode_refresh(struct gfs2_inode *ip) | |||
226 | return -EIO; | 216 | return -EIO; |
227 | } | 217 | } |
228 | 218 | ||
229 | gfs2_dinode_in(&ip->i_di, dibh->b_data); | 219 | error = gfs2_dinode_in(ip, dibh->b_data); |
230 | |||
231 | brelse(dibh); | 220 | brelse(dibh); |
221 | clear_bit(GIF_INVALID, &ip->i_flags); | ||
232 | 222 | ||
233 | if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) { | 223 | return error; |
234 | if (gfs2_consist_inode(ip)) | ||
235 | gfs2_dinode_print(&ip->i_di); | ||
236 | return -EIO; | ||
237 | } | ||
238 | if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino) | ||
239 | return -ESTALE; | ||
240 | |||
241 | ip->i_vn = ip->i_gl->gl_vn; | ||
242 | |||
243 | return 0; | ||
244 | } | 224 | } |
245 | 225 | ||
246 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) | 226 | int gfs2_dinode_dealloc(struct gfs2_inode *ip) |
@@ -252,7 +232,7 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
252 | 232 | ||
253 | if (ip->i_di.di_blocks != 1) { | 233 | if (ip->i_di.di_blocks != 1) { |
254 | if (gfs2_consist_inode(ip)) | 234 | if (gfs2_consist_inode(ip)) |
255 | gfs2_dinode_print(&ip->i_di); | 235 | gfs2_dinode_print(ip); |
256 | return -EIO; | 236 | return -EIO; |
257 | } | 237 | } |
258 | 238 | ||
@@ -315,14 +295,14 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
315 | u32 nlink; | 295 | u32 nlink; |
316 | int error; | 296 | int error; |
317 | 297 | ||
318 | BUG_ON(ip->i_di.di_nlink != ip->i_inode.i_nlink); | 298 | BUG_ON(diff != 1 && diff != -1); |
319 | nlink = ip->i_di.di_nlink + diff; | 299 | nlink = ip->i_inode.i_nlink + diff; |
320 | 300 | ||
321 | /* If we are reducing the nlink count, but the new value ends up being | 301 | /* If we are reducing the nlink count, but the new value ends up being |
322 | bigger than the old one, we must have underflowed. */ | 302 | bigger than the old one, we must have underflowed. */ |
323 | if (diff < 0 && nlink > ip->i_di.di_nlink) { | 303 | if (diff < 0 && nlink > ip->i_inode.i_nlink) { |
324 | if (gfs2_consist_inode(ip)) | 304 | if (gfs2_consist_inode(ip)) |
325 | gfs2_dinode_print(&ip->i_di); | 305 | gfs2_dinode_print(ip); |
326 | return -EIO; | 306 | return -EIO; |
327 | } | 307 | } |
328 | 308 | ||
@@ -330,16 +310,19 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
330 | if (error) | 310 | if (error) |
331 | return error; | 311 | return error; |
332 | 312 | ||
333 | ip->i_di.di_nlink = nlink; | 313 | if (diff > 0) |
334 | ip->i_di.di_ctime = get_seconds(); | 314 | inc_nlink(&ip->i_inode); |
335 | ip->i_inode.i_nlink = nlink; | 315 | else |
316 | drop_nlink(&ip->i_inode); | ||
317 | |||
318 | ip->i_inode.i_ctime.tv_sec = get_seconds(); | ||
336 | 319 | ||
337 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 320 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
338 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 321 | gfs2_dinode_out(ip, dibh->b_data); |
339 | brelse(dibh); | 322 | brelse(dibh); |
340 | mark_inode_dirty(&ip->i_inode); | 323 | mark_inode_dirty(&ip->i_inode); |
341 | 324 | ||
342 | if (ip->i_di.di_nlink == 0) { | 325 | if (ip->i_inode.i_nlink == 0) { |
343 | struct gfs2_rgrpd *rgd; | 326 | struct gfs2_rgrpd *rgd; |
344 | struct gfs2_holder ri_gh, rg_gh; | 327 | struct gfs2_holder ri_gh, rg_gh; |
345 | 328 | ||
@@ -354,7 +337,6 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
354 | if (error) | 337 | if (error) |
355 | goto out_norgrp; | 338 | goto out_norgrp; |
356 | 339 | ||
357 | clear_nlink(&ip->i_inode); | ||
358 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ | 340 | gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */ |
359 | gfs2_glock_dq_uninit(&rg_gh); | 341 | gfs2_glock_dq_uninit(&rg_gh); |
360 | out_norgrp: | 342 | out_norgrp: |
@@ -391,7 +373,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
391 | struct super_block *sb = dir->i_sb; | 373 | struct super_block *sb = dir->i_sb; |
392 | struct gfs2_inode *dip = GFS2_I(dir); | 374 | struct gfs2_inode *dip = GFS2_I(dir); |
393 | struct gfs2_holder d_gh; | 375 | struct gfs2_holder d_gh; |
394 | struct gfs2_inum inum; | 376 | struct gfs2_inum_host inum; |
395 | unsigned int type; | 377 | unsigned int type; |
396 | int error = 0; | 378 | int error = 0; |
397 | struct inode *inode = NULL; | 379 | struct inode *inode = NULL; |
@@ -433,7 +415,7 @@ static int pick_formal_ino_1(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
433 | { | 415 | { |
434 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); | 416 | struct gfs2_inode *ip = GFS2_I(sdp->sd_ir_inode); |
435 | struct buffer_head *bh; | 417 | struct buffer_head *bh; |
436 | struct gfs2_inum_range ir; | 418 | struct gfs2_inum_range_host ir; |
437 | int error; | 419 | int error; |
438 | 420 | ||
439 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 421 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); |
@@ -476,7 +458,7 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
476 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); | 458 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_inum_inode); |
477 | struct gfs2_holder gh; | 459 | struct gfs2_holder gh; |
478 | struct buffer_head *bh; | 460 | struct buffer_head *bh; |
479 | struct gfs2_inum_range ir; | 461 | struct gfs2_inum_range_host ir; |
480 | int error; | 462 | int error; |
481 | 463 | ||
482 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 464 | error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
@@ -497,21 +479,22 @@ static int pick_formal_ino_2(struct gfs2_sbd *sdp, u64 *formal_ino) | |||
497 | if (!ir.ir_length) { | 479 | if (!ir.ir_length) { |
498 | struct buffer_head *m_bh; | 480 | struct buffer_head *m_bh; |
499 | u64 x, y; | 481 | u64 x, y; |
482 | __be64 z; | ||
500 | 483 | ||
501 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); | 484 | error = gfs2_meta_inode_buffer(m_ip, &m_bh); |
502 | if (error) | 485 | if (error) |
503 | goto out_brelse; | 486 | goto out_brelse; |
504 | 487 | ||
505 | x = *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); | 488 | z = *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)); |
506 | x = y = be64_to_cpu(x); | 489 | x = y = be64_to_cpu(z); |
507 | ir.ir_start = x; | 490 | ir.ir_start = x; |
508 | ir.ir_length = GFS2_INUM_QUANTUM; | 491 | ir.ir_length = GFS2_INUM_QUANTUM; |
509 | x += GFS2_INUM_QUANTUM; | 492 | x += GFS2_INUM_QUANTUM; |
510 | if (x < y) | 493 | if (x < y) |
511 | gfs2_consist_inode(m_ip); | 494 | gfs2_consist_inode(m_ip); |
512 | x = cpu_to_be64(x); | 495 | z = cpu_to_be64(x); |
513 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); | 496 | gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1); |
514 | *(u64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = x; | 497 | *(__be64 *)(m_bh->b_data + sizeof(struct gfs2_dinode)) = z; |
515 | 498 | ||
516 | brelse(m_bh); | 499 | brelse(m_bh); |
517 | } | 500 | } |
@@ -564,7 +547,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
564 | return error; | 547 | return error; |
565 | 548 | ||
566 | /* Don't create entries in an unlinked directory */ | 549 | /* Don't create entries in an unlinked directory */ |
567 | if (!dip->i_di.di_nlink) | 550 | if (!dip->i_inode.i_nlink) |
568 | return -EPERM; | 551 | return -EPERM; |
569 | 552 | ||
570 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); | 553 | error = gfs2_dir_search(&dip->i_inode, name, NULL, NULL); |
@@ -580,7 +563,7 @@ static int create_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
580 | 563 | ||
581 | if (dip->i_di.di_entries == (u32)-1) | 564 | if (dip->i_di.di_entries == (u32)-1) |
582 | return -EFBIG; | 565 | return -EFBIG; |
583 | if (S_ISDIR(mode) && dip->i_di.di_nlink == (u32)-1) | 566 | if (S_ISDIR(mode) && dip->i_inode.i_nlink == (u32)-1) |
584 | return -EMLINK; | 567 | return -EMLINK; |
585 | 568 | ||
586 | return 0; | 569 | return 0; |
@@ -590,24 +573,24 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | |||
590 | unsigned int *uid, unsigned int *gid) | 573 | unsigned int *uid, unsigned int *gid) |
591 | { | 574 | { |
592 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && | 575 | if (GFS2_SB(&dip->i_inode)->sd_args.ar_suiddir && |
593 | (dip->i_di.di_mode & S_ISUID) && dip->i_di.di_uid) { | 576 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { |
594 | if (S_ISDIR(*mode)) | 577 | if (S_ISDIR(*mode)) |
595 | *mode |= S_ISUID; | 578 | *mode |= S_ISUID; |
596 | else if (dip->i_di.di_uid != current->fsuid) | 579 | else if (dip->i_inode.i_uid != current->fsuid) |
597 | *mode &= ~07111; | 580 | *mode &= ~07111; |
598 | *uid = dip->i_di.di_uid; | 581 | *uid = dip->i_inode.i_uid; |
599 | } else | 582 | } else |
600 | *uid = current->fsuid; | 583 | *uid = current->fsuid; |
601 | 584 | ||
602 | if (dip->i_di.di_mode & S_ISGID) { | 585 | if (dip->i_inode.i_mode & S_ISGID) { |
603 | if (S_ISDIR(*mode)) | 586 | if (S_ISDIR(*mode)) |
604 | *mode |= S_ISGID; | 587 | *mode |= S_ISGID; |
605 | *gid = dip->i_di.di_gid; | 588 | *gid = dip->i_inode.i_gid; |
606 | } else | 589 | } else |
607 | *gid = current->fsgid; | 590 | *gid = current->fsgid; |
608 | } | 591 | } |
609 | 592 | ||
610 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum *inum, | 593 | static int alloc_dinode(struct gfs2_inode *dip, struct gfs2_inum_host *inum, |
611 | u64 *generation) | 594 | u64 *generation) |
612 | { | 595 | { |
613 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 596 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
@@ -647,9 +630,9 @@ out: | |||
647 | */ | 630 | */ |
648 | 631 | ||
649 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 632 | static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
650 | const struct gfs2_inum *inum, unsigned int mode, | 633 | const struct gfs2_inum_host *inum, unsigned int mode, |
651 | unsigned int uid, unsigned int gid, | 634 | unsigned int uid, unsigned int gid, |
652 | const u64 *generation) | 635 | const u64 *generation, dev_t dev) |
653 | { | 636 | { |
654 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 637 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
655 | struct gfs2_dinode *di; | 638 | struct gfs2_dinode *di; |
@@ -666,14 +649,15 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
666 | di->di_mode = cpu_to_be32(mode); | 649 | di->di_mode = cpu_to_be32(mode); |
667 | di->di_uid = cpu_to_be32(uid); | 650 | di->di_uid = cpu_to_be32(uid); |
668 | di->di_gid = cpu_to_be32(gid); | 651 | di->di_gid = cpu_to_be32(gid); |
669 | di->di_nlink = cpu_to_be32(0); | 652 | di->di_nlink = 0; |
670 | di->di_size = cpu_to_be64(0); | 653 | di->di_size = 0; |
671 | di->di_blocks = cpu_to_be64(1); | 654 | di->di_blocks = cpu_to_be64(1); |
672 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); | 655 | di->di_atime = di->di_mtime = di->di_ctime = cpu_to_be64(get_seconds()); |
673 | di->di_major = di->di_minor = cpu_to_be32(0); | 656 | di->di_major = cpu_to_be32(MAJOR(dev)); |
657 | di->di_minor = cpu_to_be32(MINOR(dev)); | ||
674 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); | 658 | di->di_goal_meta = di->di_goal_data = cpu_to_be64(inum->no_addr); |
675 | di->di_generation = cpu_to_be64(*generation); | 659 | di->di_generation = cpu_to_be64(*generation); |
676 | di->di_flags = cpu_to_be32(0); | 660 | di->di_flags = 0; |
677 | 661 | ||
678 | if (S_ISREG(mode)) { | 662 | if (S_ISREG(mode)) { |
679 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || | 663 | if ((dip->i_di.di_flags & GFS2_DIF_INHERIT_JDATA) || |
@@ -690,22 +674,22 @@ static void init_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
690 | } | 674 | } |
691 | 675 | ||
692 | di->__pad1 = 0; | 676 | di->__pad1 = 0; |
693 | di->di_payload_format = cpu_to_be32(0); | 677 | di->di_payload_format = cpu_to_be32(S_ISDIR(mode) ? GFS2_FORMAT_DE : 0); |
694 | di->di_height = cpu_to_be32(0); | 678 | di->di_height = 0; |
695 | di->__pad2 = 0; | 679 | di->__pad2 = 0; |
696 | di->__pad3 = 0; | 680 | di->__pad3 = 0; |
697 | di->di_depth = cpu_to_be16(0); | 681 | di->di_depth = 0; |
698 | di->di_entries = cpu_to_be32(0); | 682 | di->di_entries = 0; |
699 | memset(&di->__pad4, 0, sizeof(di->__pad4)); | 683 | memset(&di->__pad4, 0, sizeof(di->__pad4)); |
700 | di->di_eattr = cpu_to_be64(0); | 684 | di->di_eattr = 0; |
701 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); | 685 | memset(&di->di_reserved, 0, sizeof(di->di_reserved)); |
702 | 686 | ||
703 | brelse(dibh); | 687 | brelse(dibh); |
704 | } | 688 | } |
705 | 689 | ||
706 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | 690 | static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, |
707 | unsigned int mode, const struct gfs2_inum *inum, | 691 | unsigned int mode, const struct gfs2_inum_host *inum, |
708 | const u64 *generation) | 692 | const u64 *generation, dev_t dev) |
709 | { | 693 | { |
710 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 694 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
711 | unsigned int uid, gid; | 695 | unsigned int uid, gid; |
@@ -726,7 +710,7 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
726 | if (error) | 710 | if (error) |
727 | goto out_quota; | 711 | goto out_quota; |
728 | 712 | ||
729 | init_dinode(dip, gl, inum, mode, uid, gid, generation); | 713 | init_dinode(dip, gl, inum, mode, uid, gid, generation, dev); |
730 | gfs2_quota_change(dip, +1, uid, gid); | 714 | gfs2_quota_change(dip, +1, uid, gid); |
731 | gfs2_trans_end(sdp); | 715 | gfs2_trans_end(sdp); |
732 | 716 | ||
@@ -756,8 +740,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
756 | if (alloc_required < 0) | 740 | if (alloc_required < 0) |
757 | goto fail; | 741 | goto fail; |
758 | if (alloc_required) { | 742 | if (alloc_required) { |
759 | error = gfs2_quota_check(dip, dip->i_di.di_uid, | 743 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
760 | dip->i_di.di_gid); | ||
761 | if (error) | 744 | if (error) |
762 | goto fail_quota_locks; | 745 | goto fail_quota_locks; |
763 | 746 | ||
@@ -779,16 +762,16 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
779 | goto fail_quota_locks; | 762 | goto fail_quota_locks; |
780 | } | 763 | } |
781 | 764 | ||
782 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_di.di_mode)); | 765 | error = gfs2_dir_add(&dip->i_inode, name, &ip->i_num, IF2DT(ip->i_inode.i_mode)); |
783 | if (error) | 766 | if (error) |
784 | goto fail_end_trans; | 767 | goto fail_end_trans; |
785 | 768 | ||
786 | error = gfs2_meta_inode_buffer(ip, &dibh); | 769 | error = gfs2_meta_inode_buffer(ip, &dibh); |
787 | if (error) | 770 | if (error) |
788 | goto fail_end_trans; | 771 | goto fail_end_trans; |
789 | ip->i_di.di_nlink = 1; | 772 | ip->i_inode.i_nlink = 1; |
790 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 773 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
791 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 774 | gfs2_dinode_out(ip, dibh->b_data); |
792 | brelse(dibh); | 775 | brelse(dibh); |
793 | return 0; | 776 | return 0; |
794 | 777 | ||
@@ -857,13 +840,13 @@ static int gfs2_security_init(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
857 | */ | 840 | */ |
858 | 841 | ||
859 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 842 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
860 | unsigned int mode) | 843 | unsigned int mode, dev_t dev) |
861 | { | 844 | { |
862 | struct inode *inode; | 845 | struct inode *inode; |
863 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; | 846 | struct gfs2_inode *dip = ghs->gh_gl->gl_object; |
864 | struct inode *dir = &dip->i_inode; | 847 | struct inode *dir = &dip->i_inode; |
865 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 848 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
866 | struct gfs2_inum inum; | 849 | struct gfs2_inum_host inum; |
867 | int error; | 850 | int error; |
868 | u64 generation; | 851 | u64 generation; |
869 | 852 | ||
@@ -887,35 +870,12 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
887 | if (error) | 870 | if (error) |
888 | goto fail_gunlock; | 871 | goto fail_gunlock; |
889 | 872 | ||
890 | if (inum.no_addr < dip->i_num.no_addr) { | 873 | error = gfs2_glock_nq_num(sdp, inum.no_addr, &gfs2_inode_glops, |
891 | gfs2_glock_dq(ghs); | 874 | LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1); |
892 | 875 | if (error) | |
893 | error = gfs2_glock_nq_num(sdp, inum.no_addr, | 876 | goto fail_gunlock; |
894 | &gfs2_inode_glops, LM_ST_EXCLUSIVE, | ||
895 | GL_SKIP, ghs + 1); | ||
896 | if (error) { | ||
897 | return ERR_PTR(error); | ||
898 | } | ||
899 | |||
900 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); | ||
901 | error = gfs2_glock_nq(ghs); | ||
902 | if (error) { | ||
903 | gfs2_glock_dq_uninit(ghs + 1); | ||
904 | return ERR_PTR(error); | ||
905 | } | ||
906 | |||
907 | error = create_ok(dip, name, mode); | ||
908 | if (error) | ||
909 | goto fail_gunlock2; | ||
910 | } else { | ||
911 | error = gfs2_glock_nq_num(sdp, inum.no_addr, | ||
912 | &gfs2_inode_glops, LM_ST_EXCLUSIVE, | ||
913 | GL_SKIP, ghs + 1); | ||
914 | if (error) | ||
915 | goto fail_gunlock; | ||
916 | } | ||
917 | 877 | ||
918 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation); | 878 | error = make_dinode(dip, ghs[1].gh_gl, mode, &inum, &generation, dev); |
919 | if (error) | 879 | if (error) |
920 | goto fail_gunlock2; | 880 | goto fail_gunlock2; |
921 | 881 | ||
@@ -972,7 +932,7 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
972 | 932 | ||
973 | if (ip->i_di.di_entries != 2) { | 933 | if (ip->i_di.di_entries != 2) { |
974 | if (gfs2_consist_inode(ip)) | 934 | if (gfs2_consist_inode(ip)) |
975 | gfs2_dinode_print(&ip->i_di); | 935 | gfs2_dinode_print(ip); |
976 | return -EIO; | 936 | return -EIO; |
977 | } | 937 | } |
978 | 938 | ||
@@ -994,7 +954,12 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
994 | if (error) | 954 | if (error) |
995 | return error; | 955 | return error; |
996 | 956 | ||
997 | error = gfs2_change_nlink(ip, -2); | 957 | /* It looks odd, but it really should be done twice */ |
958 | error = gfs2_change_nlink(ip, -1); | ||
959 | if (error) | ||
960 | return error; | ||
961 | |||
962 | error = gfs2_change_nlink(ip, -1); | ||
998 | if (error) | 963 | if (error) |
999 | return error; | 964 | return error; |
1000 | 965 | ||
@@ -1015,16 +980,16 @@ int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | |||
1015 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 980 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
1016 | struct gfs2_inode *ip) | 981 | struct gfs2_inode *ip) |
1017 | { | 982 | { |
1018 | struct gfs2_inum inum; | 983 | struct gfs2_inum_host inum; |
1019 | unsigned int type; | 984 | unsigned int type; |
1020 | int error; | 985 | int error; |
1021 | 986 | ||
1022 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) | 987 | if (IS_IMMUTABLE(&ip->i_inode) || IS_APPEND(&ip->i_inode)) |
1023 | return -EPERM; | 988 | return -EPERM; |
1024 | 989 | ||
1025 | if ((dip->i_di.di_mode & S_ISVTX) && | 990 | if ((dip->i_inode.i_mode & S_ISVTX) && |
1026 | dip->i_di.di_uid != current->fsuid && | 991 | dip->i_inode.i_uid != current->fsuid && |
1027 | ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) | 992 | ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER)) |
1028 | return -EPERM; | 993 | return -EPERM; |
1029 | 994 | ||
1030 | if (IS_APPEND(&dip->i_inode)) | 995 | if (IS_APPEND(&dip->i_inode)) |
@@ -1041,7 +1006,7 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | |||
1041 | if (!gfs2_inum_equal(&inum, &ip->i_num)) | 1006 | if (!gfs2_inum_equal(&inum, &ip->i_num)) |
1042 | return -ENOENT; | 1007 | return -ENOENT; |
1043 | 1008 | ||
1044 | if (IF2DT(ip->i_di.di_mode) != type) { | 1009 | if (IF2DT(ip->i_inode.i_mode) != type) { |
1045 | gfs2_consist_inode(dip); | 1010 | gfs2_consist_inode(dip); |
1046 | return -EIO; | 1011 | return -EIO; |
1047 | } | 1012 | } |
@@ -1191,7 +1156,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1191 | return 0; | 1156 | return 0; |
1192 | 1157 | ||
1193 | curtime = get_seconds(); | 1158 | curtime = get_seconds(); |
1194 | if (curtime - ip->i_di.di_atime >= quantum) { | 1159 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { |
1195 | gfs2_glock_dq(gh); | 1160 | gfs2_glock_dq(gh); |
1196 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, | 1161 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, |
1197 | gh); | 1162 | gh); |
@@ -1203,7 +1168,7 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1203 | trying to get exclusive lock. */ | 1168 | trying to get exclusive lock. */ |
1204 | 1169 | ||
1205 | curtime = get_seconds(); | 1170 | curtime = get_seconds(); |
1206 | if (curtime - ip->i_di.di_atime >= quantum) { | 1171 | if (curtime - ip->i_inode.i_atime.tv_sec >= quantum) { |
1207 | struct buffer_head *dibh; | 1172 | struct buffer_head *dibh; |
1208 | struct gfs2_dinode *di; | 1173 | struct gfs2_dinode *di; |
1209 | 1174 | ||
@@ -1217,11 +1182,11 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
1217 | if (error) | 1182 | if (error) |
1218 | goto fail_end_trans; | 1183 | goto fail_end_trans; |
1219 | 1184 | ||
1220 | ip->i_di.di_atime = curtime; | 1185 | ip->i_inode.i_atime.tv_sec = curtime; |
1221 | 1186 | ||
1222 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1187 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1223 | di = (struct gfs2_dinode *)dibh->b_data; | 1188 | di = (struct gfs2_dinode *)dibh->b_data; |
1224 | di->di_atime = cpu_to_be64(ip->i_di.di_atime); | 1189 | di->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1225 | brelse(dibh); | 1190 | brelse(dibh); |
1226 | 1191 | ||
1227 | gfs2_trans_end(sdp); | 1192 | gfs2_trans_end(sdp); |
@@ -1246,92 +1211,6 @@ fail: | |||
1246 | return error; | 1211 | return error; |
1247 | } | 1212 | } |
1248 | 1213 | ||
1249 | /** | ||
1250 | * glock_compare_atime - Compare two struct gfs2_glock structures for sort | ||
1251 | * @arg_a: the first structure | ||
1252 | * @arg_b: the second structure | ||
1253 | * | ||
1254 | * Returns: 1 if A > B | ||
1255 | * -1 if A < B | ||
1256 | * 0 if A == B | ||
1257 | */ | ||
1258 | |||
1259 | static int glock_compare_atime(const void *arg_a, const void *arg_b) | ||
1260 | { | ||
1261 | const struct gfs2_holder *gh_a = *(const struct gfs2_holder **)arg_a; | ||
1262 | const struct gfs2_holder *gh_b = *(const struct gfs2_holder **)arg_b; | ||
1263 | const struct lm_lockname *a = &gh_a->gh_gl->gl_name; | ||
1264 | const struct lm_lockname *b = &gh_b->gh_gl->gl_name; | ||
1265 | |||
1266 | if (a->ln_number > b->ln_number) | ||
1267 | return 1; | ||
1268 | if (a->ln_number < b->ln_number) | ||
1269 | return -1; | ||
1270 | if (gh_a->gh_state == LM_ST_SHARED && gh_b->gh_state == LM_ST_EXCLUSIVE) | ||
1271 | return 1; | ||
1272 | if (gh_a->gh_state == LM_ST_SHARED && (gh_b->gh_flags & GL_ATIME)) | ||
1273 | return 1; | ||
1274 | |||
1275 | return 0; | ||
1276 | } | ||
1277 | |||
1278 | /** | ||
1279 | * gfs2_glock_nq_m_atime - acquire multiple glocks where one may need an | ||
1280 | * atime update | ||
1281 | * @num_gh: the number of structures | ||
1282 | * @ghs: an array of struct gfs2_holder structures | ||
1283 | * | ||
1284 | * Returns: 0 on success (all glocks acquired), | ||
1285 | * errno on failure (no glocks acquired) | ||
1286 | */ | ||
1287 | |||
1288 | int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs) | ||
1289 | { | ||
1290 | struct gfs2_holder **p; | ||
1291 | unsigned int x; | ||
1292 | int error = 0; | ||
1293 | |||
1294 | if (!num_gh) | ||
1295 | return 0; | ||
1296 | |||
1297 | if (num_gh == 1) { | ||
1298 | ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | ||
1299 | if (ghs->gh_flags & GL_ATIME) | ||
1300 | error = gfs2_glock_nq_atime(ghs); | ||
1301 | else | ||
1302 | error = gfs2_glock_nq(ghs); | ||
1303 | return error; | ||
1304 | } | ||
1305 | |||
1306 | p = kcalloc(num_gh, sizeof(struct gfs2_holder *), GFP_KERNEL); | ||
1307 | if (!p) | ||
1308 | return -ENOMEM; | ||
1309 | |||
1310 | for (x = 0; x < num_gh; x++) | ||
1311 | p[x] = &ghs[x]; | ||
1312 | |||
1313 | sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare_atime,NULL); | ||
1314 | |||
1315 | for (x = 0; x < num_gh; x++) { | ||
1316 | p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); | ||
1317 | |||
1318 | if (p[x]->gh_flags & GL_ATIME) | ||
1319 | error = gfs2_glock_nq_atime(p[x]); | ||
1320 | else | ||
1321 | error = gfs2_glock_nq(p[x]); | ||
1322 | |||
1323 | if (error) { | ||
1324 | while (x--) | ||
1325 | gfs2_glock_dq(p[x]); | ||
1326 | break; | ||
1327 | } | ||
1328 | } | ||
1329 | |||
1330 | kfree(p); | ||
1331 | return error; | ||
1332 | } | ||
1333 | |||
1334 | |||
1335 | static int | 1214 | static int |
1336 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | 1215 | __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) |
1337 | { | 1216 | { |
@@ -1342,10 +1221,8 @@ __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr) | |||
1342 | if (!error) { | 1221 | if (!error) { |
1343 | error = inode_setattr(&ip->i_inode, attr); | 1222 | error = inode_setattr(&ip->i_inode, attr); |
1344 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); | 1223 | gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error); |
1345 | gfs2_inode_attr_out(ip); | ||
1346 | |||
1347 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 1224 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
1348 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 1225 | gfs2_dinode_out(ip, dibh->b_data); |
1349 | brelse(dibh); | 1226 | brelse(dibh); |
1350 | } | 1227 | } |
1351 | return error; | 1228 | return error; |
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index f5d861760579..b57f448b15bc 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h | |||
@@ -22,13 +22,19 @@ static inline int gfs2_is_jdata(struct gfs2_inode *ip) | |||
22 | 22 | ||
23 | static inline int gfs2_is_dir(struct gfs2_inode *ip) | 23 | static inline int gfs2_is_dir(struct gfs2_inode *ip) |
24 | { | 24 | { |
25 | return S_ISDIR(ip->i_di.di_mode); | 25 | return S_ISDIR(ip->i_inode.i_mode); |
26 | } | ||
27 | |||
28 | static inline void gfs2_set_inode_blocks(struct inode *inode) | ||
29 | { | ||
30 | struct gfs2_inode *ip = GFS2_I(inode); | ||
31 | inode->i_blocks = ip->i_di.di_blocks << | ||
32 | (GFS2_SB(inode)->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT); | ||
26 | } | 33 | } |
27 | 34 | ||
28 | void gfs2_inode_attr_in(struct gfs2_inode *ip); | 35 | void gfs2_inode_attr_in(struct gfs2_inode *ip); |
29 | void gfs2_inode_attr_out(struct gfs2_inode *ip); | 36 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum_host *inum, unsigned type); |
30 | struct inode *gfs2_inode_lookup(struct super_block *sb, struct gfs2_inum *inum, unsigned type); | 37 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum); |
31 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum *inum); | ||
32 | 38 | ||
33 | int gfs2_inode_refresh(struct gfs2_inode *ip); | 39 | int gfs2_inode_refresh(struct gfs2_inode *ip); |
34 | 40 | ||
@@ -37,19 +43,15 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff); | |||
37 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | 43 | struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, |
38 | int is_root, struct nameidata *nd); | 44 | int is_root, struct nameidata *nd); |
39 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | 45 | struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, |
40 | unsigned int mode); | 46 | unsigned int mode, dev_t dev); |
41 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, | 47 | int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, |
42 | struct gfs2_inode *ip); | 48 | struct gfs2_inode *ip); |
43 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, | 49 | int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name, |
44 | struct gfs2_inode *ip); | 50 | struct gfs2_inode *ip); |
45 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); | 51 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to); |
46 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); | 52 | int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len); |
47 | |||
48 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); | 53 | int gfs2_glock_nq_atime(struct gfs2_holder *gh); |
49 | int gfs2_glock_nq_m_atime(unsigned int num_gh, struct gfs2_holder *ghs); | ||
50 | |||
51 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); | 54 | int gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr); |
52 | |||
53 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); | 55 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name); |
54 | 56 | ||
55 | #endif /* __INODE_DOT_H__ */ | 57 | #endif /* __INODE_DOT_H__ */ |
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c index 7365aec9511b..3799f19b282f 100644 --- a/fs/gfs2/locking/dlm/plock.c +++ b/fs/gfs2/locking/dlm/plock.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/miscdevice.h> | 9 | #include <linux/miscdevice.h> |
10 | #include <linux/lock_dlm_plock.h> | 10 | #include <linux/lock_dlm_plock.h> |
11 | #include <linux/poll.h> | ||
11 | 12 | ||
12 | #include "lock_dlm.h" | 13 | #include "lock_dlm.h" |
13 | 14 | ||
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 0cace3da9dbb..291415ddfe51 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
16 | #include <linux/crc32.h> | 16 | #include <linux/crc32.h> |
17 | #include <linux/lm_interface.h> | 17 | #include <linux/lm_interface.h> |
18 | #include <linux/delay.h> | ||
18 | 19 | ||
19 | #include "gfs2.h" | 20 | #include "gfs2.h" |
20 | #include "incore.h" | 21 | #include "incore.h" |
@@ -142,7 +143,7 @@ static int gfs2_ail1_empty_one(struct gfs2_sbd *sdp, struct gfs2_ail *ai, int fl | |||
142 | return list_empty(&ai->ai_ail1_list); | 143 | return list_empty(&ai->ai_ail1_list); |
143 | } | 144 | } |
144 | 145 | ||
145 | void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) | 146 | static void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags) |
146 | { | 147 | { |
147 | struct list_head *head = &sdp->sd_ail1_list; | 148 | struct list_head *head = &sdp->sd_ail1_list; |
148 | u64 sync_gen; | 149 | u64 sync_gen; |
@@ -261,6 +262,12 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
261 | * @sdp: The GFS2 superblock | 262 | * @sdp: The GFS2 superblock |
262 | * @blks: The number of blocks to reserve | 263 | * @blks: The number of blocks to reserve |
263 | * | 264 | * |
265 | * Note that we never give out the last 6 blocks of the journal. Thats | ||
266 | * due to the fact that there is are a small number of header blocks | ||
267 | * associated with each log flush. The exact number can't be known until | ||
268 | * flush time, so we ensure that we have just enough free blocks at all | ||
269 | * times to avoid running out during a log flush. | ||
270 | * | ||
264 | * Returns: errno | 271 | * Returns: errno |
265 | */ | 272 | */ |
266 | 273 | ||
@@ -274,7 +281,7 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks) | |||
274 | 281 | ||
275 | mutex_lock(&sdp->sd_log_reserve_mutex); | 282 | mutex_lock(&sdp->sd_log_reserve_mutex); |
276 | gfs2_log_lock(sdp); | 283 | gfs2_log_lock(sdp); |
277 | while(sdp->sd_log_blks_free <= blks) { | 284 | while(sdp->sd_log_blks_free <= (blks + 6)) { |
278 | gfs2_log_unlock(sdp); | 285 | gfs2_log_unlock(sdp); |
279 | gfs2_ail1_empty(sdp, 0); | 286 | gfs2_ail1_empty(sdp, 0); |
280 | gfs2_log_flush(sdp, NULL); | 287 | gfs2_log_flush(sdp, NULL); |
@@ -319,7 +326,8 @@ static u64 log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) | |||
319 | bh_map.b_size = 1 << inode->i_blkbits; | 326 | bh_map.b_size = 1 << inode->i_blkbits; |
320 | error = gfs2_block_map(inode, lbn, 0, &bh_map); | 327 | error = gfs2_block_map(inode, lbn, 0, &bh_map); |
321 | if (error || !bh_map.b_blocknr) | 328 | if (error || !bh_map.b_blocknr) |
322 | printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, bh_map.b_blocknr, lbn); | 329 | printk(KERN_INFO "error=%d, dbn=%llu lbn=%u", error, |
330 | (unsigned long long)bh_map.b_blocknr, lbn); | ||
323 | gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); | 331 | gfs2_assert_withdraw(sdp, !error && bh_map.b_blocknr); |
324 | 332 | ||
325 | return bh_map.b_blocknr; | 333 | return bh_map.b_blocknr; |
@@ -643,12 +651,9 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | |||
643 | up_read(&sdp->sd_log_flush_lock); | 651 | up_read(&sdp->sd_log_flush_lock); |
644 | 652 | ||
645 | gfs2_log_lock(sdp); | 653 | gfs2_log_lock(sdp); |
646 | if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) { | 654 | if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) |
647 | gfs2_log_unlock(sdp); | 655 | wake_up_process(sdp->sd_logd_process); |
648 | gfs2_log_flush(sdp, NULL); | 656 | gfs2_log_unlock(sdp); |
649 | } else { | ||
650 | gfs2_log_unlock(sdp); | ||
651 | } | ||
652 | } | 657 | } |
653 | 658 | ||
654 | /** | 659 | /** |
@@ -686,3 +691,21 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) | |||
686 | up_write(&sdp->sd_log_flush_lock); | 691 | up_write(&sdp->sd_log_flush_lock); |
687 | } | 692 | } |
688 | 693 | ||
694 | |||
695 | /** | ||
696 | * gfs2_meta_syncfs - sync all the buffers in a filesystem | ||
697 | * @sdp: the filesystem | ||
698 | * | ||
699 | */ | ||
700 | |||
701 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | ||
702 | { | ||
703 | gfs2_log_flush(sdp, NULL); | ||
704 | for (;;) { | ||
705 | gfs2_ail1_start(sdp, DIO_ALL); | ||
706 | if (gfs2_ail1_empty(sdp, DIO_ALL)) | ||
707 | break; | ||
708 | msleep(10); | ||
709 | } | ||
710 | } | ||
711 | |||
diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index 7f5737d55612..8e7aa0f29109 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h | |||
@@ -48,7 +48,6 @@ static inline void gfs2_log_pointers_init(struct gfs2_sbd *sdp, | |||
48 | unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, | 48 | unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, |
49 | unsigned int ssize); | 49 | unsigned int ssize); |
50 | 50 | ||
51 | void gfs2_ail1_start(struct gfs2_sbd *sdp, int flags); | ||
52 | int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags); | 51 | int gfs2_ail1_empty(struct gfs2_sbd *sdp, int flags); |
53 | 52 | ||
54 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); | 53 | int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); |
@@ -61,5 +60,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl); | |||
61 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); | 60 | void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); |
62 | 61 | ||
63 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); | 62 | void gfs2_log_shutdown(struct gfs2_sbd *sdp); |
63 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | ||
64 | 64 | ||
65 | #endif /* __LOG_DOT_H__ */ | 65 | #endif /* __LOG_DOT_H__ */ |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index ab6d1115f95d..4d7f94d8c7bd 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -182,7 +182,7 @@ static void buf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
182 | } | 182 | } |
183 | 183 | ||
184 | static void buf_lo_before_scan(struct gfs2_jdesc *jd, | 184 | static void buf_lo_before_scan(struct gfs2_jdesc *jd, |
185 | struct gfs2_log_header *head, int pass) | 185 | struct gfs2_log_header_host *head, int pass) |
186 | { | 186 | { |
187 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 187 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
188 | 188 | ||
@@ -328,7 +328,7 @@ static void revoke_lo_before_commit(struct gfs2_sbd *sdp) | |||
328 | } | 328 | } |
329 | 329 | ||
330 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, | 330 | static void revoke_lo_before_scan(struct gfs2_jdesc *jd, |
331 | struct gfs2_log_header *head, int pass) | 331 | struct gfs2_log_header_host *head, int pass) |
332 | { | 332 | { |
333 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 333 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
334 | 334 | ||
@@ -509,7 +509,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
509 | { | 509 | { |
510 | LIST_HEAD(started); | 510 | LIST_HEAD(started); |
511 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; | 511 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; |
512 | struct buffer_head *bh = NULL; | 512 | struct buffer_head *bh = NULL,*bh1 = NULL; |
513 | unsigned int offset = sizeof(struct gfs2_log_descriptor); | 513 | unsigned int offset = sizeof(struct gfs2_log_descriptor); |
514 | struct gfs2_log_descriptor *ld; | 514 | struct gfs2_log_descriptor *ld; |
515 | unsigned int limit; | 515 | unsigned int limit; |
@@ -537,8 +537,13 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
537 | list_for_each_entry_safe_continue(bd1, bdt, | 537 | list_for_each_entry_safe_continue(bd1, bdt, |
538 | &sdp->sd_log_le_databuf, | 538 | &sdp->sd_log_le_databuf, |
539 | bd_le.le_list) { | 539 | bd_le.le_list) { |
540 | /* store off the buffer head in a local ptr since | ||
541 | * gfs2_bufdata might change when we drop the log lock | ||
542 | */ | ||
543 | bh1 = bd1->bd_bh; | ||
544 | |||
540 | /* An ordered write buffer */ | 545 | /* An ordered write buffer */ |
541 | if (bd1->bd_bh && !buffer_pinned(bd1->bd_bh)) { | 546 | if (bh1 && !buffer_pinned(bh1)) { |
542 | list_move(&bd1->bd_le.le_list, &started); | 547 | list_move(&bd1->bd_le.le_list, &started); |
543 | if (bd1 == bd2) { | 548 | if (bd1 == bd2) { |
544 | bd2 = NULL; | 549 | bd2 = NULL; |
@@ -547,20 +552,21 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
547 | bd_le.le_list); | 552 | bd_le.le_list); |
548 | } | 553 | } |
549 | total_dbuf--; | 554 | total_dbuf--; |
550 | if (bd1->bd_bh) { | 555 | if (bh1) { |
551 | get_bh(bd1->bd_bh); | 556 | if (buffer_dirty(bh1)) { |
552 | if (buffer_dirty(bd1->bd_bh)) { | 557 | get_bh(bh1); |
558 | |||
553 | gfs2_log_unlock(sdp); | 559 | gfs2_log_unlock(sdp); |
554 | wait_on_buffer(bd1->bd_bh); | 560 | |
555 | ll_rw_block(WRITE, 1, | 561 | ll_rw_block(SWRITE, 1, &bh1); |
556 | &bd1->bd_bh); | 562 | brelse(bh1); |
563 | |||
557 | gfs2_log_lock(sdp); | 564 | gfs2_log_lock(sdp); |
558 | } | 565 | } |
559 | brelse(bd1->bd_bh); | ||
560 | continue; | 566 | continue; |
561 | } | 567 | } |
562 | continue; | 568 | continue; |
563 | } else if (bd1->bd_bh) { /* A journaled buffer */ | 569 | } else if (bh1) { /* A journaled buffer */ |
564 | int magic; | 570 | int magic; |
565 | gfs2_log_unlock(sdp); | 571 | gfs2_log_unlock(sdp); |
566 | if (!bh) { | 572 | if (!bh) { |
@@ -582,16 +588,16 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
582 | ld->ld_data2 = cpu_to_be32(0); | 588 | ld->ld_data2 = cpu_to_be32(0); |
583 | memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); | 589 | memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved)); |
584 | } | 590 | } |
585 | magic = gfs2_check_magic(bd1->bd_bh); | 591 | magic = gfs2_check_magic(bh1); |
586 | *ptr++ = cpu_to_be64(bd1->bd_bh->b_blocknr); | 592 | *ptr++ = cpu_to_be64(bh1->b_blocknr); |
587 | *ptr++ = cpu_to_be64((__u64)magic); | 593 | *ptr++ = cpu_to_be64((__u64)magic); |
588 | clear_buffer_escaped(bd1->bd_bh); | 594 | clear_buffer_escaped(bh1); |
589 | if (unlikely(magic != 0)) | 595 | if (unlikely(magic != 0)) |
590 | set_buffer_escaped(bd1->bd_bh); | 596 | set_buffer_escaped(bh1); |
591 | gfs2_log_lock(sdp); | 597 | gfs2_log_lock(sdp); |
592 | if (n++ > num) | 598 | if (n++ > num) |
593 | break; | 599 | break; |
594 | } else if (!bd1->bd_bh) { | 600 | } else if (!bh1) { |
595 | total_dbuf--; | 601 | total_dbuf--; |
596 | sdp->sd_log_num_databuf--; | 602 | sdp->sd_log_num_databuf--; |
597 | list_del_init(&bd1->bd_le.le_list); | 603 | list_del_init(&bd1->bd_le.le_list); |
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index 5839c05ae6be..965bc65c7c64 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h | |||
@@ -60,7 +60,7 @@ static inline void lops_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai) | |||
60 | } | 60 | } |
61 | 61 | ||
62 | static inline void lops_before_scan(struct gfs2_jdesc *jd, | 62 | static inline void lops_before_scan(struct gfs2_jdesc *jd, |
63 | struct gfs2_log_header *head, | 63 | struct gfs2_log_header_host *head, |
64 | unsigned int pass) | 64 | unsigned int pass) |
65 | { | 65 | { |
66 | int x; | 66 | int x; |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index 21508a13bb78..7c1a9e22a526 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include "util.h" | 25 | #include "util.h" |
26 | #include "glock.h" | 26 | #include "glock.h" |
27 | 27 | ||
28 | static void gfs2_init_inode_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 28 | static void gfs2_init_inode_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
29 | { | 29 | { |
30 | struct gfs2_inode *ip = foo; | 30 | struct gfs2_inode *ip = foo; |
31 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 31 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == |
@@ -37,7 +37,7 @@ static void gfs2_init_inode_once(void *foo, kmem_cache_t *cachep, unsigned long | |||
37 | } | 37 | } |
38 | } | 38 | } |
39 | 39 | ||
40 | static void gfs2_init_glock_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 40 | static void gfs2_init_glock_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
41 | { | 41 | { |
42 | struct gfs2_glock *gl = foo; | 42 | struct gfs2_glock *gl = foo; |
43 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == | 43 | if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == |
@@ -84,8 +84,8 @@ static int __init init_gfs2_fs(void) | |||
84 | 84 | ||
85 | gfs2_inode_cachep = kmem_cache_create("gfs2_inode", | 85 | gfs2_inode_cachep = kmem_cache_create("gfs2_inode", |
86 | sizeof(struct gfs2_inode), | 86 | sizeof(struct gfs2_inode), |
87 | 0, (SLAB_RECLAIM_ACCOUNT| | 87 | 0, SLAB_RECLAIM_ACCOUNT| |
88 | SLAB_PANIC|SLAB_MEM_SPREAD), | 88 | SLAB_MEM_SPREAD, |
89 | gfs2_init_inode_once, NULL); | 89 | gfs2_init_inode_once, NULL); |
90 | if (!gfs2_inode_cachep) | 90 | if (!gfs2_inode_cachep) |
91 | goto fail; | 91 | goto fail; |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 3912d6a4b1e6..0e34d9918973 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -127,17 +127,17 @@ void gfs2_meta_sync(struct gfs2_glock *gl) | |||
127 | 127 | ||
128 | /** | 128 | /** |
129 | * getbuf - Get a buffer with a given address space | 129 | * getbuf - Get a buffer with a given address space |
130 | * @sdp: the filesystem | 130 | * @gl: the glock |
131 | * @aspace: the address space | ||
132 | * @blkno: the block number (filesystem scope) | 131 | * @blkno: the block number (filesystem scope) |
133 | * @create: 1 if the buffer should be created | 132 | * @create: 1 if the buffer should be created |
134 | * | 133 | * |
135 | * Returns: the buffer | 134 | * Returns: the buffer |
136 | */ | 135 | */ |
137 | 136 | ||
138 | static struct buffer_head *getbuf(struct gfs2_sbd *sdp, struct inode *aspace, | 137 | static struct buffer_head *getbuf(struct gfs2_glock *gl, u64 blkno, int create) |
139 | u64 blkno, int create) | ||
140 | { | 138 | { |
139 | struct address_space *mapping = gl->gl_aspace->i_mapping; | ||
140 | struct gfs2_sbd *sdp = gl->gl_sbd; | ||
141 | struct page *page; | 141 | struct page *page; |
142 | struct buffer_head *bh; | 142 | struct buffer_head *bh; |
143 | unsigned int shift; | 143 | unsigned int shift; |
@@ -150,13 +150,13 @@ static struct buffer_head *getbuf(struct gfs2_sbd *sdp, struct inode *aspace, | |||
150 | 150 | ||
151 | if (create) { | 151 | if (create) { |
152 | for (;;) { | 152 | for (;;) { |
153 | page = grab_cache_page(aspace->i_mapping, index); | 153 | page = grab_cache_page(mapping, index); |
154 | if (page) | 154 | if (page) |
155 | break; | 155 | break; |
156 | yield(); | 156 | yield(); |
157 | } | 157 | } |
158 | } else { | 158 | } else { |
159 | page = find_lock_page(aspace->i_mapping, index); | 159 | page = find_lock_page(mapping, index); |
160 | if (!page) | 160 | if (!page) |
161 | return NULL; | 161 | return NULL; |
162 | } | 162 | } |
@@ -202,7 +202,7 @@ static void meta_prep_new(struct buffer_head *bh) | |||
202 | struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | 202 | struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) |
203 | { | 203 | { |
204 | struct buffer_head *bh; | 204 | struct buffer_head *bh; |
205 | bh = getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); | 205 | bh = getbuf(gl, blkno, CREATE); |
206 | meta_prep_new(bh); | 206 | meta_prep_new(bh); |
207 | return bh; | 207 | return bh; |
208 | } | 208 | } |
@@ -220,7 +220,7 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) | |||
220 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | 220 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, |
221 | struct buffer_head **bhp) | 221 | struct buffer_head **bhp) |
222 | { | 222 | { |
223 | *bhp = getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); | 223 | *bhp = getbuf(gl, blkno, CREATE); |
224 | if (!buffer_uptodate(*bhp)) | 224 | if (!buffer_uptodate(*bhp)) |
225 | ll_rw_block(READ_META, 1, bhp); | 225 | ll_rw_block(READ_META, 1, bhp); |
226 | if (flags & DIO_WAIT) { | 226 | if (flags & DIO_WAIT) { |
@@ -379,11 +379,10 @@ void gfs2_unpin(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
379 | void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | 379 | void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) |
380 | { | 380 | { |
381 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 381 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
382 | struct inode *aspace = ip->i_gl->gl_aspace; | ||
383 | struct buffer_head *bh; | 382 | struct buffer_head *bh; |
384 | 383 | ||
385 | while (blen) { | 384 | while (blen) { |
386 | bh = getbuf(sdp, aspace, bstart, NO_CREATE); | 385 | bh = getbuf(ip->i_gl, bstart, NO_CREATE); |
387 | if (bh) { | 386 | if (bh) { |
388 | struct gfs2_bufdata *bd = bh->b_private; | 387 | struct gfs2_bufdata *bd = bh->b_private; |
389 | 388 | ||
@@ -472,6 +471,9 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
472 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; | 471 | struct buffer_head *bh = NULL, **bh_slot = ip->i_cache + height; |
473 | int in_cache = 0; | 472 | int in_cache = 0; |
474 | 473 | ||
474 | BUG_ON(!gl); | ||
475 | BUG_ON(!sdp); | ||
476 | |||
475 | spin_lock(&ip->i_spin); | 477 | spin_lock(&ip->i_spin); |
476 | if (*bh_slot && (*bh_slot)->b_blocknr == num) { | 478 | if (*bh_slot && (*bh_slot)->b_blocknr == num) { |
477 | bh = *bh_slot; | 479 | bh = *bh_slot; |
@@ -481,7 +483,7 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, | |||
481 | spin_unlock(&ip->i_spin); | 483 | spin_unlock(&ip->i_spin); |
482 | 484 | ||
483 | if (!bh) | 485 | if (!bh) |
484 | bh = getbuf(gl->gl_sbd, gl->gl_aspace, num, CREATE); | 486 | bh = getbuf(gl, num, CREATE); |
485 | 487 | ||
486 | if (!bh) | 488 | if (!bh) |
487 | return -ENOBUFS; | 489 | return -ENOBUFS; |
@@ -532,7 +534,6 @@ err: | |||
532 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | 534 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) |
533 | { | 535 | { |
534 | struct gfs2_sbd *sdp = gl->gl_sbd; | 536 | struct gfs2_sbd *sdp = gl->gl_sbd; |
535 | struct inode *aspace = gl->gl_aspace; | ||
536 | struct buffer_head *first_bh, *bh; | 537 | struct buffer_head *first_bh, *bh; |
537 | u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >> | 538 | u32 max_ra = gfs2_tune_get(sdp, gt_max_readahead) >> |
538 | sdp->sd_sb.sb_bsize_shift; | 539 | sdp->sd_sb.sb_bsize_shift; |
@@ -544,7 +545,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | |||
544 | if (extlen > max_ra) | 545 | if (extlen > max_ra) |
545 | extlen = max_ra; | 546 | extlen = max_ra; |
546 | 547 | ||
547 | first_bh = getbuf(sdp, aspace, dblock, CREATE); | 548 | first_bh = getbuf(gl, dblock, CREATE); |
548 | 549 | ||
549 | if (buffer_uptodate(first_bh)) | 550 | if (buffer_uptodate(first_bh)) |
550 | goto out; | 551 | goto out; |
@@ -555,7 +556,7 @@ struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen) | |||
555 | extlen--; | 556 | extlen--; |
556 | 557 | ||
557 | while (extlen) { | 558 | while (extlen) { |
558 | bh = getbuf(sdp, aspace, dblock, CREATE); | 559 | bh = getbuf(gl, dblock, CREATE); |
559 | 560 | ||
560 | if (!buffer_uptodate(bh) && !buffer_locked(bh)) | 561 | if (!buffer_uptodate(bh) && !buffer_locked(bh)) |
561 | ll_rw_block(READA, 1, &bh); | 562 | ll_rw_block(READA, 1, &bh); |
@@ -571,20 +572,3 @@ out: | |||
571 | return first_bh; | 572 | return first_bh; |
572 | } | 573 | } |
573 | 574 | ||
574 | /** | ||
575 | * gfs2_meta_syncfs - sync all the buffers in a filesystem | ||
576 | * @sdp: the filesystem | ||
577 | * | ||
578 | */ | ||
579 | |||
580 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | ||
581 | { | ||
582 | gfs2_log_flush(sdp, NULL); | ||
583 | for (;;) { | ||
584 | gfs2_ail1_start(sdp, DIO_ALL); | ||
585 | if (gfs2_ail1_empty(sdp, DIO_ALL)) | ||
586 | break; | ||
587 | msleep(10); | ||
588 | } | ||
589 | } | ||
590 | |||
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h index 3ec939e20dff..e037425bc042 100644 --- a/fs/gfs2/meta_io.h +++ b/fs/gfs2/meta_io.h | |||
@@ -67,7 +67,6 @@ static inline int gfs2_meta_inode_buffer(struct gfs2_inode *ip, | |||
67 | } | 67 | } |
68 | 68 | ||
69 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); | 69 | struct buffer_head *gfs2_meta_ra(struct gfs2_glock *gl, u64 dblock, u32 extlen); |
70 | void gfs2_meta_syncfs(struct gfs2_sbd *sdp); | ||
71 | 70 | ||
72 | #define buffer_busy(bh) \ | 71 | #define buffer_busy(bh) \ |
73 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned))) | 72 | ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock) | (1ul << BH_Pinned))) |
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c index 1025960b0e6e..f2495f1e21ad 100644 --- a/fs/gfs2/ondisk.c +++ b/fs/gfs2/ondisk.c | |||
@@ -15,6 +15,8 @@ | |||
15 | 15 | ||
16 | #include "gfs2.h" | 16 | #include "gfs2.h" |
17 | #include <linux/gfs2_ondisk.h> | 17 | #include <linux/gfs2_ondisk.h> |
18 | #include <linux/lm_interface.h> | ||
19 | #include "incore.h" | ||
18 | 20 | ||
19 | #define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \ | 21 | #define pv(struct, member, fmt) printk(KERN_INFO " "#member" = "fmt"\n", \ |
20 | struct->member); | 22 | struct->member); |
@@ -32,7 +34,7 @@ | |||
32 | * first arg: the cpu-order structure | 34 | * first arg: the cpu-order structure |
33 | */ | 35 | */ |
34 | 36 | ||
35 | void gfs2_inum_in(struct gfs2_inum *no, const void *buf) | 37 | void gfs2_inum_in(struct gfs2_inum_host *no, const void *buf) |
36 | { | 38 | { |
37 | const struct gfs2_inum *str = buf; | 39 | const struct gfs2_inum *str = buf; |
38 | 40 | ||
@@ -40,7 +42,7 @@ void gfs2_inum_in(struct gfs2_inum *no, const void *buf) | |||
40 | no->no_addr = be64_to_cpu(str->no_addr); | 42 | no->no_addr = be64_to_cpu(str->no_addr); |
41 | } | 43 | } |
42 | 44 | ||
43 | void gfs2_inum_out(const struct gfs2_inum *no, void *buf) | 45 | void gfs2_inum_out(const struct gfs2_inum_host *no, void *buf) |
44 | { | 46 | { |
45 | struct gfs2_inum *str = buf; | 47 | struct gfs2_inum *str = buf; |
46 | 48 | ||
@@ -48,13 +50,13 @@ void gfs2_inum_out(const struct gfs2_inum *no, void *buf) | |||
48 | str->no_addr = cpu_to_be64(no->no_addr); | 50 | str->no_addr = cpu_to_be64(no->no_addr); |
49 | } | 51 | } |
50 | 52 | ||
51 | static void gfs2_inum_print(const struct gfs2_inum *no) | 53 | static void gfs2_inum_print(const struct gfs2_inum_host *no) |
52 | { | 54 | { |
53 | printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino); | 55 | printk(KERN_INFO " no_formal_ino = %llu\n", (unsigned long long)no->no_formal_ino); |
54 | printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr); | 56 | printk(KERN_INFO " no_addr = %llu\n", (unsigned long long)no->no_addr); |
55 | } | 57 | } |
56 | 58 | ||
57 | static void gfs2_meta_header_in(struct gfs2_meta_header *mh, const void *buf) | 59 | static void gfs2_meta_header_in(struct gfs2_meta_header_host *mh, const void *buf) |
58 | { | 60 | { |
59 | const struct gfs2_meta_header *str = buf; | 61 | const struct gfs2_meta_header *str = buf; |
60 | 62 | ||
@@ -63,23 +65,7 @@ static void gfs2_meta_header_in(struct gfs2_meta_header *mh, const void *buf) | |||
63 | mh->mh_format = be32_to_cpu(str->mh_format); | 65 | mh->mh_format = be32_to_cpu(str->mh_format); |
64 | } | 66 | } |
65 | 67 | ||
66 | static void gfs2_meta_header_out(const struct gfs2_meta_header *mh, void *buf) | 68 | void gfs2_sb_in(struct gfs2_sb_host *sb, const void *buf) |
67 | { | ||
68 | struct gfs2_meta_header *str = buf; | ||
69 | |||
70 | str->mh_magic = cpu_to_be32(mh->mh_magic); | ||
71 | str->mh_type = cpu_to_be32(mh->mh_type); | ||
72 | str->mh_format = cpu_to_be32(mh->mh_format); | ||
73 | } | ||
74 | |||
75 | static void gfs2_meta_header_print(const struct gfs2_meta_header *mh) | ||
76 | { | ||
77 | pv(mh, mh_magic, "0x%.8X"); | ||
78 | pv(mh, mh_type, "%u"); | ||
79 | pv(mh, mh_format, "%u"); | ||
80 | } | ||
81 | |||
82 | void gfs2_sb_in(struct gfs2_sb *sb, const void *buf) | ||
83 | { | 69 | { |
84 | const struct gfs2_sb *str = buf; | 70 | const struct gfs2_sb *str = buf; |
85 | 71 | ||
@@ -97,7 +83,7 @@ void gfs2_sb_in(struct gfs2_sb *sb, const void *buf) | |||
97 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); | 83 | memcpy(sb->sb_locktable, str->sb_locktable, GFS2_LOCKNAME_LEN); |
98 | } | 84 | } |
99 | 85 | ||
100 | void gfs2_rindex_in(struct gfs2_rindex *ri, const void *buf) | 86 | void gfs2_rindex_in(struct gfs2_rindex_host *ri, const void *buf) |
101 | { | 87 | { |
102 | const struct gfs2_rindex *str = buf; | 88 | const struct gfs2_rindex *str = buf; |
103 | 89 | ||
@@ -109,7 +95,7 @@ void gfs2_rindex_in(struct gfs2_rindex *ri, const void *buf) | |||
109 | 95 | ||
110 | } | 96 | } |
111 | 97 | ||
112 | void gfs2_rindex_print(const struct gfs2_rindex *ri) | 98 | void gfs2_rindex_print(const struct gfs2_rindex_host *ri) |
113 | { | 99 | { |
114 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr); | 100 | printk(KERN_INFO " ri_addr = %llu\n", (unsigned long long)ri->ri_addr); |
115 | pv(ri, ri_length, "%u"); | 101 | pv(ri, ri_length, "%u"); |
@@ -120,22 +106,20 @@ void gfs2_rindex_print(const struct gfs2_rindex *ri) | |||
120 | pv(ri, ri_bitbytes, "%u"); | 106 | pv(ri, ri_bitbytes, "%u"); |
121 | } | 107 | } |
122 | 108 | ||
123 | void gfs2_rgrp_in(struct gfs2_rgrp *rg, const void *buf) | 109 | void gfs2_rgrp_in(struct gfs2_rgrp_host *rg, const void *buf) |
124 | { | 110 | { |
125 | const struct gfs2_rgrp *str = buf; | 111 | const struct gfs2_rgrp *str = buf; |
126 | 112 | ||
127 | gfs2_meta_header_in(&rg->rg_header, buf); | ||
128 | rg->rg_flags = be32_to_cpu(str->rg_flags); | 113 | rg->rg_flags = be32_to_cpu(str->rg_flags); |
129 | rg->rg_free = be32_to_cpu(str->rg_free); | 114 | rg->rg_free = be32_to_cpu(str->rg_free); |
130 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); | 115 | rg->rg_dinodes = be32_to_cpu(str->rg_dinodes); |
131 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); | 116 | rg->rg_igeneration = be64_to_cpu(str->rg_igeneration); |
132 | } | 117 | } |
133 | 118 | ||
134 | void gfs2_rgrp_out(const struct gfs2_rgrp *rg, void *buf) | 119 | void gfs2_rgrp_out(const struct gfs2_rgrp_host *rg, void *buf) |
135 | { | 120 | { |
136 | struct gfs2_rgrp *str = buf; | 121 | struct gfs2_rgrp *str = buf; |
137 | 122 | ||
138 | gfs2_meta_header_out(&rg->rg_header, buf); | ||
139 | str->rg_flags = cpu_to_be32(rg->rg_flags); | 123 | str->rg_flags = cpu_to_be32(rg->rg_flags); |
140 | str->rg_free = cpu_to_be32(rg->rg_free); | 124 | str->rg_free = cpu_to_be32(rg->rg_free); |
141 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); | 125 | str->rg_dinodes = cpu_to_be32(rg->rg_dinodes); |
@@ -144,7 +128,7 @@ void gfs2_rgrp_out(const struct gfs2_rgrp *rg, void *buf) | |||
144 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); | 128 | memset(&str->rg_reserved, 0, sizeof(str->rg_reserved)); |
145 | } | 129 | } |
146 | 130 | ||
147 | void gfs2_quota_in(struct gfs2_quota *qu, const void *buf) | 131 | void gfs2_quota_in(struct gfs2_quota_host *qu, const void *buf) |
148 | { | 132 | { |
149 | const struct gfs2_quota *str = buf; | 133 | const struct gfs2_quota *str = buf; |
150 | 134 | ||
@@ -153,96 +137,56 @@ void gfs2_quota_in(struct gfs2_quota *qu, const void *buf) | |||
153 | qu->qu_value = be64_to_cpu(str->qu_value); | 137 | qu->qu_value = be64_to_cpu(str->qu_value); |
154 | } | 138 | } |
155 | 139 | ||
156 | void gfs2_dinode_in(struct gfs2_dinode *di, const void *buf) | 140 | void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) |
157 | { | ||
158 | const struct gfs2_dinode *str = buf; | ||
159 | |||
160 | gfs2_meta_header_in(&di->di_header, buf); | ||
161 | gfs2_inum_in(&di->di_num, &str->di_num); | ||
162 | |||
163 | di->di_mode = be32_to_cpu(str->di_mode); | ||
164 | di->di_uid = be32_to_cpu(str->di_uid); | ||
165 | di->di_gid = be32_to_cpu(str->di_gid); | ||
166 | di->di_nlink = be32_to_cpu(str->di_nlink); | ||
167 | di->di_size = be64_to_cpu(str->di_size); | ||
168 | di->di_blocks = be64_to_cpu(str->di_blocks); | ||
169 | di->di_atime = be64_to_cpu(str->di_atime); | ||
170 | di->di_mtime = be64_to_cpu(str->di_mtime); | ||
171 | di->di_ctime = be64_to_cpu(str->di_ctime); | ||
172 | di->di_major = be32_to_cpu(str->di_major); | ||
173 | di->di_minor = be32_to_cpu(str->di_minor); | ||
174 | |||
175 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | ||
176 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | ||
177 | di->di_generation = be64_to_cpu(str->di_generation); | ||
178 | |||
179 | di->di_flags = be32_to_cpu(str->di_flags); | ||
180 | di->di_payload_format = be32_to_cpu(str->di_payload_format); | ||
181 | di->di_height = be16_to_cpu(str->di_height); | ||
182 | |||
183 | di->di_depth = be16_to_cpu(str->di_depth); | ||
184 | di->di_entries = be32_to_cpu(str->di_entries); | ||
185 | |||
186 | di->di_eattr = be64_to_cpu(str->di_eattr); | ||
187 | |||
188 | } | ||
189 | |||
190 | void gfs2_dinode_out(const struct gfs2_dinode *di, void *buf) | ||
191 | { | 141 | { |
142 | const struct gfs2_dinode_host *di = &ip->i_di; | ||
192 | struct gfs2_dinode *str = buf; | 143 | struct gfs2_dinode *str = buf; |
193 | 144 | ||
194 | gfs2_meta_header_out(&di->di_header, buf); | 145 | str->di_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
195 | gfs2_inum_out(&di->di_num, (char *)&str->di_num); | 146 | str->di_header.mh_type = cpu_to_be32(GFS2_METATYPE_DI); |
147 | str->di_header.__pad0 = 0; | ||
148 | str->di_header.mh_format = cpu_to_be32(GFS2_FORMAT_DI); | ||
149 | str->di_header.__pad1 = 0; | ||
196 | 150 | ||
197 | str->di_mode = cpu_to_be32(di->di_mode); | 151 | gfs2_inum_out(&ip->i_num, &str->di_num); |
198 | str->di_uid = cpu_to_be32(di->di_uid); | 152 | |
199 | str->di_gid = cpu_to_be32(di->di_gid); | 153 | str->di_mode = cpu_to_be32(ip->i_inode.i_mode); |
200 | str->di_nlink = cpu_to_be32(di->di_nlink); | 154 | str->di_uid = cpu_to_be32(ip->i_inode.i_uid); |
155 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | ||
156 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | ||
201 | str->di_size = cpu_to_be64(di->di_size); | 157 | str->di_size = cpu_to_be64(di->di_size); |
202 | str->di_blocks = cpu_to_be64(di->di_blocks); | 158 | str->di_blocks = cpu_to_be64(di->di_blocks); |
203 | str->di_atime = cpu_to_be64(di->di_atime); | 159 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
204 | str->di_mtime = cpu_to_be64(di->di_mtime); | 160 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); |
205 | str->di_ctime = cpu_to_be64(di->di_ctime); | 161 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); |
206 | str->di_major = cpu_to_be32(di->di_major); | ||
207 | str->di_minor = cpu_to_be32(di->di_minor); | ||
208 | 162 | ||
209 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); | 163 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); |
210 | str->di_goal_data = cpu_to_be64(di->di_goal_data); | 164 | str->di_goal_data = cpu_to_be64(di->di_goal_data); |
211 | str->di_generation = cpu_to_be64(di->di_generation); | 165 | str->di_generation = cpu_to_be64(di->di_generation); |
212 | 166 | ||
213 | str->di_flags = cpu_to_be32(di->di_flags); | 167 | str->di_flags = cpu_to_be32(di->di_flags); |
214 | str->di_payload_format = cpu_to_be32(di->di_payload_format); | ||
215 | str->di_height = cpu_to_be16(di->di_height); | 168 | str->di_height = cpu_to_be16(di->di_height); |
216 | 169 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | |
170 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | ||
171 | GFS2_FORMAT_DE : 0); | ||
217 | str->di_depth = cpu_to_be16(di->di_depth); | 172 | str->di_depth = cpu_to_be16(di->di_depth); |
218 | str->di_entries = cpu_to_be32(di->di_entries); | 173 | str->di_entries = cpu_to_be32(di->di_entries); |
219 | 174 | ||
220 | str->di_eattr = cpu_to_be64(di->di_eattr); | 175 | str->di_eattr = cpu_to_be64(di->di_eattr); |
221 | |||
222 | } | 176 | } |
223 | 177 | ||
224 | void gfs2_dinode_print(const struct gfs2_dinode *di) | 178 | void gfs2_dinode_print(const struct gfs2_inode *ip) |
225 | { | 179 | { |
226 | gfs2_meta_header_print(&di->di_header); | 180 | const struct gfs2_dinode_host *di = &ip->i_di; |
227 | gfs2_inum_print(&di->di_num); | 181 | |
182 | gfs2_inum_print(&ip->i_num); | ||
228 | 183 | ||
229 | pv(di, di_mode, "0%o"); | ||
230 | pv(di, di_uid, "%u"); | ||
231 | pv(di, di_gid, "%u"); | ||
232 | pv(di, di_nlink, "%u"); | ||
233 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); | 184 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); |
234 | printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); | 185 | printk(KERN_INFO " di_blocks = %llu\n", (unsigned long long)di->di_blocks); |
235 | printk(KERN_INFO " di_atime = %lld\n", (long long)di->di_atime); | ||
236 | printk(KERN_INFO " di_mtime = %lld\n", (long long)di->di_mtime); | ||
237 | printk(KERN_INFO " di_ctime = %lld\n", (long long)di->di_ctime); | ||
238 | pv(di, di_major, "%u"); | ||
239 | pv(di, di_minor, "%u"); | ||
240 | |||
241 | printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta); | 186 | printk(KERN_INFO " di_goal_meta = %llu\n", (unsigned long long)di->di_goal_meta); |
242 | printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data); | 187 | printk(KERN_INFO " di_goal_data = %llu\n", (unsigned long long)di->di_goal_data); |
243 | 188 | ||
244 | pv(di, di_flags, "0x%.8X"); | 189 | pv(di, di_flags, "0x%.8X"); |
245 | pv(di, di_payload_format, "%u"); | ||
246 | pv(di, di_height, "%u"); | 190 | pv(di, di_height, "%u"); |
247 | 191 | ||
248 | pv(di, di_depth, "%u"); | 192 | pv(di, di_depth, "%u"); |
@@ -251,7 +195,7 @@ void gfs2_dinode_print(const struct gfs2_dinode *di) | |||
251 | printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr); | 195 | printk(KERN_INFO " di_eattr = %llu\n", (unsigned long long)di->di_eattr); |
252 | } | 196 | } |
253 | 197 | ||
254 | void gfs2_log_header_in(struct gfs2_log_header *lh, const void *buf) | 198 | void gfs2_log_header_in(struct gfs2_log_header_host *lh, const void *buf) |
255 | { | 199 | { |
256 | const struct gfs2_log_header *str = buf; | 200 | const struct gfs2_log_header *str = buf; |
257 | 201 | ||
@@ -263,7 +207,7 @@ void gfs2_log_header_in(struct gfs2_log_header *lh, const void *buf) | |||
263 | lh->lh_hash = be32_to_cpu(str->lh_hash); | 207 | lh->lh_hash = be32_to_cpu(str->lh_hash); |
264 | } | 208 | } |
265 | 209 | ||
266 | void gfs2_inum_range_in(struct gfs2_inum_range *ir, const void *buf) | 210 | void gfs2_inum_range_in(struct gfs2_inum_range_host *ir, const void *buf) |
267 | { | 211 | { |
268 | const struct gfs2_inum_range *str = buf; | 212 | const struct gfs2_inum_range *str = buf; |
269 | 213 | ||
@@ -271,7 +215,7 @@ void gfs2_inum_range_in(struct gfs2_inum_range *ir, const void *buf) | |||
271 | ir->ir_length = be64_to_cpu(str->ir_length); | 215 | ir->ir_length = be64_to_cpu(str->ir_length); |
272 | } | 216 | } |
273 | 217 | ||
274 | void gfs2_inum_range_out(const struct gfs2_inum_range *ir, void *buf) | 218 | void gfs2_inum_range_out(const struct gfs2_inum_range_host *ir, void *buf) |
275 | { | 219 | { |
276 | struct gfs2_inum_range *str = buf; | 220 | struct gfs2_inum_range *str = buf; |
277 | 221 | ||
@@ -279,7 +223,7 @@ void gfs2_inum_range_out(const struct gfs2_inum_range *ir, void *buf) | |||
279 | str->ir_length = cpu_to_be64(ir->ir_length); | 223 | str->ir_length = cpu_to_be64(ir->ir_length); |
280 | } | 224 | } |
281 | 225 | ||
282 | void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, const void *buf) | 226 | void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) |
283 | { | 227 | { |
284 | const struct gfs2_statfs_change *str = buf; | 228 | const struct gfs2_statfs_change *str = buf; |
285 | 229 | ||
@@ -288,7 +232,7 @@ void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, const void *buf) | |||
288 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); | 232 | sc->sc_dinodes = be64_to_cpu(str->sc_dinodes); |
289 | } | 233 | } |
290 | 234 | ||
291 | void gfs2_statfs_change_out(const struct gfs2_statfs_change *sc, void *buf) | 235 | void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc, void *buf) |
292 | { | 236 | { |
293 | struct gfs2_statfs_change *str = buf; | 237 | struct gfs2_statfs_change *str = buf; |
294 | 238 | ||
@@ -297,7 +241,7 @@ void gfs2_statfs_change_out(const struct gfs2_statfs_change *sc, void *buf) | |||
297 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); | 241 | str->sc_dinodes = cpu_to_be64(sc->sc_dinodes); |
298 | } | 242 | } |
299 | 243 | ||
300 | void gfs2_quota_change_in(struct gfs2_quota_change *qc, const void *buf) | 244 | void gfs2_quota_change_in(struct gfs2_quota_change_host *qc, const void *buf) |
301 | { | 245 | { |
302 | const struct gfs2_quota_change *str = buf; | 246 | const struct gfs2_quota_change *str = buf; |
303 | 247 | ||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 015640b3f123..d8d69a72a10d 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -156,19 +156,6 @@ out_ignore: | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int zero_readpage(struct page *page) | ||
160 | { | ||
161 | void *kaddr; | ||
162 | |||
163 | kaddr = kmap_atomic(page, KM_USER0); | ||
164 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
165 | kunmap_atomic(kaddr, KM_USER0); | ||
166 | |||
167 | SetPageUptodate(page); | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | /** | 159 | /** |
173 | * stuffed_readpage - Fill in a Linux page with stuffed file data | 160 | * stuffed_readpage - Fill in a Linux page with stuffed file data |
174 | * @ip: the inode | 161 | * @ip: the inode |
@@ -183,9 +170,7 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | |||
183 | void *kaddr; | 170 | void *kaddr; |
184 | int error; | 171 | int error; |
185 | 172 | ||
186 | /* Only the first page of a stuffed file might contain data */ | 173 | BUG_ON(page->index); |
187 | if (unlikely(page->index)) | ||
188 | return zero_readpage(page); | ||
189 | 174 | ||
190 | error = gfs2_meta_inode_buffer(ip, &dibh); | 175 | error = gfs2_meta_inode_buffer(ip, &dibh); |
191 | if (error) | 176 | if (error) |
@@ -230,9 +215,9 @@ static int gfs2_readpage(struct file *file, struct page *page) | |||
230 | /* gfs2_sharewrite_nopage has grabbed the ip->i_gl already */ | 215 | /* gfs2_sharewrite_nopage has grabbed the ip->i_gl already */ |
231 | goto skip_lock; | 216 | goto skip_lock; |
232 | } | 217 | } |
233 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh); | 218 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); |
234 | do_unlock = 1; | 219 | do_unlock = 1; |
235 | error = gfs2_glock_nq_m_atime(1, &gh); | 220 | error = gfs2_glock_nq_atime(&gh); |
236 | if (unlikely(error)) | 221 | if (unlikely(error)) |
237 | goto out_unlock; | 222 | goto out_unlock; |
238 | } | 223 | } |
@@ -254,6 +239,8 @@ skip_lock: | |||
254 | out: | 239 | out: |
255 | return error; | 240 | return error; |
256 | out_unlock: | 241 | out_unlock: |
242 | if (error == GLR_TRYFAILED) | ||
243 | error = AOP_TRUNCATED_PAGE; | ||
257 | unlock_page(page); | 244 | unlock_page(page); |
258 | if (do_unlock) | 245 | if (do_unlock) |
259 | gfs2_holder_uninit(&gh); | 246 | gfs2_holder_uninit(&gh); |
@@ -293,9 +280,9 @@ static int gfs2_readpages(struct file *file, struct address_space *mapping, | |||
293 | goto skip_lock; | 280 | goto skip_lock; |
294 | } | 281 | } |
295 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, | 282 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, |
296 | LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh); | 283 | LM_FLAG_TRY_1CB|GL_ATIME, &gh); |
297 | do_unlock = 1; | 284 | do_unlock = 1; |
298 | ret = gfs2_glock_nq_m_atime(1, &gh); | 285 | ret = gfs2_glock_nq_atime(&gh); |
299 | if (ret == GLR_TRYFAILED) | 286 | if (ret == GLR_TRYFAILED) |
300 | goto out_noerror; | 287 | goto out_noerror; |
301 | if (unlikely(ret)) | 288 | if (unlikely(ret)) |
@@ -366,10 +353,13 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
366 | unsigned int write_len = to - from; | 353 | unsigned int write_len = to - from; |
367 | 354 | ||
368 | 355 | ||
369 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|GL_AOP, &ip->i_gh); | 356 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|LM_FLAG_TRY_1CB, &ip->i_gh); |
370 | error = gfs2_glock_nq_m_atime(1, &ip->i_gh); | 357 | error = gfs2_glock_nq_atime(&ip->i_gh); |
371 | if (error) | 358 | if (unlikely(error)) { |
359 | if (error == GLR_TRYFAILED) | ||
360 | error = AOP_TRUNCATED_PAGE; | ||
372 | goto out_uninit; | 361 | goto out_uninit; |
362 | } | ||
373 | 363 | ||
374 | gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks); | 364 | gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks); |
375 | 365 | ||
@@ -386,7 +376,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
386 | if (error) | 376 | if (error) |
387 | goto out_alloc_put; | 377 | goto out_alloc_put; |
388 | 378 | ||
389 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 379 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
390 | if (error) | 380 | if (error) |
391 | goto out_qunlock; | 381 | goto out_qunlock; |
392 | 382 | ||
@@ -482,8 +472,10 @@ static int gfs2_commit_write(struct file *file, struct page *page, | |||
482 | 472 | ||
483 | SetPageUptodate(page); | 473 | SetPageUptodate(page); |
484 | 474 | ||
485 | if (inode->i_size < file_size) | 475 | if (inode->i_size < file_size) { |
486 | i_size_write(inode, file_size); | 476 | i_size_write(inode, file_size); |
477 | mark_inode_dirty(inode); | ||
478 | } | ||
487 | } else { | 479 | } else { |
488 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || | 480 | if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || |
489 | gfs2_is_jdata(ip)) | 481 | gfs2_is_jdata(ip)) |
@@ -498,11 +490,6 @@ static int gfs2_commit_write(struct file *file, struct page *page, | |||
498 | di->di_size = cpu_to_be64(inode->i_size); | 490 | di->di_size = cpu_to_be64(inode->i_size); |
499 | } | 491 | } |
500 | 492 | ||
501 | di->di_mode = cpu_to_be32(inode->i_mode); | ||
502 | di->di_atime = cpu_to_be64(inode->i_atime.tv_sec); | ||
503 | di->di_mtime = cpu_to_be64(inode->i_mtime.tv_sec); | ||
504 | di->di_ctime = cpu_to_be64(inode->i_ctime.tv_sec); | ||
505 | |||
506 | brelse(dibh); | 493 | brelse(dibh); |
507 | gfs2_trans_end(sdp); | 494 | gfs2_trans_end(sdp); |
508 | if (al->al_requested) { | 495 | if (al->al_requested) { |
@@ -624,7 +611,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | |||
624 | * on this path. All we need change is atime. | 611 | * on this path. All we need change is atime. |
625 | */ | 612 | */ |
626 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 613 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
627 | rv = gfs2_glock_nq_m_atime(1, &gh); | 614 | rv = gfs2_glock_nq_atime(&gh); |
628 | if (rv) | 615 | if (rv) |
629 | goto out; | 616 | goto out; |
630 | 617 | ||
@@ -737,6 +724,9 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
737 | if (!atomic_read(&aspace->i_writecount)) | 724 | if (!atomic_read(&aspace->i_writecount)) |
738 | return 0; | 725 | return 0; |
739 | 726 | ||
727 | if (!(gfp_mask & __GFP_WAIT)) | ||
728 | return 0; | ||
729 | |||
740 | if (time_after_eq(jiffies, t)) { | 730 | if (time_after_eq(jiffies, t)) { |
741 | stuck_releasepage(bh); | 731 | stuck_releasepage(bh); |
742 | /* should we withdraw here? */ | 732 | /* should we withdraw here? */ |
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c index 00041b1b8025..d355899585d8 100644 --- a/fs/gfs2/ops_dentry.c +++ b/fs/gfs2/ops_dentry.c | |||
@@ -43,7 +43,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
43 | struct inode *inode = dentry->d_inode; | 43 | struct inode *inode = dentry->d_inode; |
44 | struct gfs2_holder d_gh; | 44 | struct gfs2_holder d_gh; |
45 | struct gfs2_inode *ip; | 45 | struct gfs2_inode *ip; |
46 | struct gfs2_inum inum; | 46 | struct gfs2_inum_host inum; |
47 | unsigned int type; | 47 | unsigned int type; |
48 | int error; | 48 | int error; |
49 | 49 | ||
@@ -76,7 +76,7 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) | |||
76 | if (!gfs2_inum_equal(&ip->i_num, &inum)) | 76 | if (!gfs2_inum_equal(&ip->i_num, &inum)) |
77 | goto invalid_gunlock; | 77 | goto invalid_gunlock; |
78 | 78 | ||
79 | if (IF2DT(ip->i_di.di_mode) != type) { | 79 | if (IF2DT(ip->i_inode.i_mode) != type) { |
80 | gfs2_consist_inode(dip); | 80 | gfs2_consist_inode(dip); |
81 | goto fail_gunlock; | 81 | goto fail_gunlock; |
82 | } | 82 | } |
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index 86127d93bd35..b4e7b8775315 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -27,15 +27,16 @@ | |||
27 | #include "util.h" | 27 | #include "util.h" |
28 | 28 | ||
29 | static struct dentry *gfs2_decode_fh(struct super_block *sb, | 29 | static struct dentry *gfs2_decode_fh(struct super_block *sb, |
30 | __u32 *fh, | 30 | __u32 *p, |
31 | int fh_len, | 31 | int fh_len, |
32 | int fh_type, | 32 | int fh_type, |
33 | int (*acceptable)(void *context, | 33 | int (*acceptable)(void *context, |
34 | struct dentry *dentry), | 34 | struct dentry *dentry), |
35 | void *context) | 35 | void *context) |
36 | { | 36 | { |
37 | __be32 *fh = (__force __be32 *)p; | ||
37 | struct gfs2_fh_obj fh_obj; | 38 | struct gfs2_fh_obj fh_obj; |
38 | struct gfs2_inum *this, parent; | 39 | struct gfs2_inum_host *this, parent; |
39 | 40 | ||
40 | if (fh_type != fh_len) | 41 | if (fh_type != fh_len) |
41 | return NULL; | 42 | return NULL; |
@@ -65,9 +66,10 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, | |||
65 | acceptable, context); | 66 | acceptable, context); |
66 | } | 67 | } |
67 | 68 | ||
68 | static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | 69 | static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, |
69 | int connectable) | 70 | int connectable) |
70 | { | 71 | { |
72 | __be32 *fh = (__force __be32 *)p; | ||
71 | struct inode *inode = dentry->d_inode; | 73 | struct inode *inode = dentry->d_inode; |
72 | struct super_block *sb = inode->i_sb; | 74 | struct super_block *sb = inode->i_sb; |
73 | struct gfs2_inode *ip = GFS2_I(inode); | 75 | struct gfs2_inode *ip = GFS2_I(inode); |
@@ -76,14 +78,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
76 | (connectable && *len < GFS2_LARGE_FH_SIZE)) | 78 | (connectable && *len < GFS2_LARGE_FH_SIZE)) |
77 | return 255; | 79 | return 255; |
78 | 80 | ||
79 | fh[0] = ip->i_num.no_formal_ino >> 32; | 81 | fh[0] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); |
80 | fh[0] = cpu_to_be32(fh[0]); | 82 | fh[1] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); |
81 | fh[1] = ip->i_num.no_formal_ino & 0xFFFFFFFF; | 83 | fh[2] = cpu_to_be32(ip->i_num.no_addr >> 32); |
82 | fh[1] = cpu_to_be32(fh[1]); | 84 | fh[3] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); |
83 | fh[2] = ip->i_num.no_addr >> 32; | ||
84 | fh[2] = cpu_to_be32(fh[2]); | ||
85 | fh[3] = ip->i_num.no_addr & 0xFFFFFFFF; | ||
86 | fh[3] = cpu_to_be32(fh[3]); | ||
87 | *len = GFS2_SMALL_FH_SIZE; | 85 | *len = GFS2_SMALL_FH_SIZE; |
88 | 86 | ||
89 | if (!connectable || inode == sb->s_root->d_inode) | 87 | if (!connectable || inode == sb->s_root->d_inode) |
@@ -95,14 +93,10 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
95 | igrab(inode); | 93 | igrab(inode); |
96 | spin_unlock(&dentry->d_lock); | 94 | spin_unlock(&dentry->d_lock); |
97 | 95 | ||
98 | fh[4] = ip->i_num.no_formal_ino >> 32; | 96 | fh[4] = cpu_to_be32(ip->i_num.no_formal_ino >> 32); |
99 | fh[4] = cpu_to_be32(fh[4]); | 97 | fh[5] = cpu_to_be32(ip->i_num.no_formal_ino & 0xFFFFFFFF); |
100 | fh[5] = ip->i_num.no_formal_ino & 0xFFFFFFFF; | 98 | fh[6] = cpu_to_be32(ip->i_num.no_addr >> 32); |
101 | fh[5] = cpu_to_be32(fh[5]); | 99 | fh[7] = cpu_to_be32(ip->i_num.no_addr & 0xFFFFFFFF); |
102 | fh[6] = ip->i_num.no_addr >> 32; | ||
103 | fh[6] = cpu_to_be32(fh[6]); | ||
104 | fh[7] = ip->i_num.no_addr & 0xFFFFFFFF; | ||
105 | fh[7] = cpu_to_be32(fh[7]); | ||
106 | 100 | ||
107 | fh[8] = cpu_to_be32(inode->i_mode); | 101 | fh[8] = cpu_to_be32(inode->i_mode); |
108 | fh[9] = 0; /* pad to double word */ | 102 | fh[9] = 0; /* pad to double word */ |
@@ -114,12 +108,12 @@ static int gfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *len, | |||
114 | } | 108 | } |
115 | 109 | ||
116 | struct get_name_filldir { | 110 | struct get_name_filldir { |
117 | struct gfs2_inum inum; | 111 | struct gfs2_inum_host inum; |
118 | char *name; | 112 | char *name; |
119 | }; | 113 | }; |
120 | 114 | ||
121 | static int get_name_filldir(void *opaque, const char *name, unsigned int length, | 115 | static int get_name_filldir(void *opaque, const char *name, unsigned int length, |
122 | u64 offset, struct gfs2_inum *inum, | 116 | u64 offset, struct gfs2_inum_host *inum, |
123 | unsigned int type) | 117 | unsigned int type) |
124 | { | 118 | { |
125 | struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; | 119 | struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; |
@@ -202,7 +196,7 @@ static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) | |||
202 | { | 196 | { |
203 | struct gfs2_sbd *sdp = sb->s_fs_info; | 197 | struct gfs2_sbd *sdp = sb->s_fs_info; |
204 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; | 198 | struct gfs2_fh_obj *fh_obj = (struct gfs2_fh_obj *)inum_obj; |
205 | struct gfs2_inum *inum = &fh_obj->this; | 199 | struct gfs2_inum_host *inum = &fh_obj->this; |
206 | struct gfs2_holder i_gh, ri_gh, rgd_gh; | 200 | struct gfs2_holder i_gh, ri_gh, rgd_gh; |
207 | struct gfs2_rgrpd *rgd; | 201 | struct gfs2_rgrpd *rgd; |
208 | struct inode *inode; | 202 | struct inode *inode; |
diff --git a/fs/gfs2/ops_export.h b/fs/gfs2/ops_export.h index 09aca5046fb1..f925a955b3b8 100644 --- a/fs/gfs2/ops_export.h +++ b/fs/gfs2/ops_export.h | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | extern struct export_operations gfs2_export_ops; | 16 | extern struct export_operations gfs2_export_ops; |
17 | struct gfs2_fh_obj { | 17 | struct gfs2_fh_obj { |
18 | struct gfs2_inum this; | 18 | struct gfs2_inum_host this; |
19 | __u32 imode; | 19 | __u32 imode; |
20 | }; | 20 | }; |
21 | 21 | ||
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c index 3064f133bf3c..b3f1e0349ae0 100644 --- a/fs/gfs2/ops_file.c +++ b/fs/gfs2/ops_file.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/ext2_fs.h> | 22 | #include <linux/ext2_fs.h> |
23 | #include <linux/crc32.h> | 23 | #include <linux/crc32.h> |
24 | #include <linux/lm_interface.h> | 24 | #include <linux/lm_interface.h> |
25 | #include <linux/writeback.h> | ||
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | 27 | ||
27 | #include "gfs2.h" | 28 | #include "gfs2.h" |
@@ -71,7 +72,7 @@ static int gfs2_read_actor(read_descriptor_t *desc, struct page *page, | |||
71 | size = count; | 72 | size = count; |
72 | 73 | ||
73 | kaddr = kmap(page); | 74 | kaddr = kmap(page); |
74 | memcpy(desc->arg.buf, kaddr + offset, size); | 75 | memcpy(desc->arg.data, kaddr + offset, size); |
75 | kunmap(page); | 76 | kunmap(page); |
76 | 77 | ||
77 | desc->count = count - size; | 78 | desc->count = count - size; |
@@ -86,7 +87,7 @@ int gfs2_internal_read(struct gfs2_inode *ip, struct file_ra_state *ra_state, | |||
86 | struct inode *inode = &ip->i_inode; | 87 | struct inode *inode = &ip->i_inode; |
87 | read_descriptor_t desc; | 88 | read_descriptor_t desc; |
88 | desc.written = 0; | 89 | desc.written = 0; |
89 | desc.arg.buf = buf; | 90 | desc.arg.data = buf; |
90 | desc.count = size; | 91 | desc.count = size; |
91 | desc.error = 0; | 92 | desc.error = 0; |
92 | do_generic_mapping_read(inode->i_mapping, ra_state, | 93 | do_generic_mapping_read(inode->i_mapping, ra_state, |
@@ -139,7 +140,7 @@ static loff_t gfs2_llseek(struct file *file, loff_t offset, int origin) | |||
139 | */ | 140 | */ |
140 | 141 | ||
141 | static int filldir_func(void *opaque, const char *name, unsigned int length, | 142 | static int filldir_func(void *opaque, const char *name, unsigned int length, |
142 | u64 offset, struct gfs2_inum *inum, | 143 | u64 offset, struct gfs2_inum_host *inum, |
143 | unsigned int type) | 144 | unsigned int type) |
144 | { | 145 | { |
145 | struct filldir_reg *fdr = (struct filldir_reg *)opaque; | 146 | struct filldir_reg *fdr = (struct filldir_reg *)opaque; |
@@ -253,7 +254,7 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
253 | u32 fsflags; | 254 | u32 fsflags; |
254 | 255 | ||
255 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); | 256 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
256 | error = gfs2_glock_nq_m_atime(1, &gh); | 257 | error = gfs2_glock_nq_atime(&gh); |
257 | if (error) | 258 | if (error) |
258 | return error; | 259 | return error; |
259 | 260 | ||
@@ -266,6 +267,24 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) | |||
266 | return error; | 267 | return error; |
267 | } | 268 | } |
268 | 269 | ||
270 | void gfs2_set_inode_flags(struct inode *inode) | ||
271 | { | ||
272 | struct gfs2_inode *ip = GFS2_I(inode); | ||
273 | struct gfs2_dinode_host *di = &ip->i_di; | ||
274 | unsigned int flags = inode->i_flags; | ||
275 | |||
276 | flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | ||
277 | if (di->di_flags & GFS2_DIF_IMMUTABLE) | ||
278 | flags |= S_IMMUTABLE; | ||
279 | if (di->di_flags & GFS2_DIF_APPENDONLY) | ||
280 | flags |= S_APPEND; | ||
281 | if (di->di_flags & GFS2_DIF_NOATIME) | ||
282 | flags |= S_NOATIME; | ||
283 | if (di->di_flags & GFS2_DIF_SYNC) | ||
284 | flags |= S_SYNC; | ||
285 | inode->i_flags = flags; | ||
286 | } | ||
287 | |||
269 | /* Flags that can be set by user space */ | 288 | /* Flags that can be set by user space */ |
270 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ | 289 | #define GFS2_FLAGS_USER_SET (GFS2_DIF_JDATA| \ |
271 | GFS2_DIF_DIRECTIO| \ | 290 | GFS2_DIF_DIRECTIO| \ |
@@ -336,8 +355,9 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) | |||
336 | goto out_trans_end; | 355 | goto out_trans_end; |
337 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 356 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
338 | ip->i_di.di_flags = new_flags; | 357 | ip->i_di.di_flags = new_flags; |
339 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 358 | gfs2_dinode_out(ip, bh->b_data); |
340 | brelse(bh); | 359 | brelse(bh); |
360 | gfs2_set_inode_flags(inode); | ||
341 | out_trans_end: | 361 | out_trans_end: |
342 | gfs2_trans_end(sdp); | 362 | gfs2_trans_end(sdp); |
343 | out: | 363 | out: |
@@ -425,7 +445,7 @@ static int gfs2_open(struct inode *inode, struct file *file) | |||
425 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); | 445 | gfs2_assert_warn(GFS2_SB(inode), !file->private_data); |
426 | file->private_data = fp; | 446 | file->private_data = fp; |
427 | 447 | ||
428 | if (S_ISREG(ip->i_di.di_mode)) { | 448 | if (S_ISREG(ip->i_inode.i_mode)) { |
429 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, | 449 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, |
430 | &i_gh); | 450 | &i_gh); |
431 | if (error) | 451 | if (error) |
@@ -484,16 +504,40 @@ static int gfs2_close(struct inode *inode, struct file *file) | |||
484 | * @file: the file that points to the dentry (we ignore this) | 504 | * @file: the file that points to the dentry (we ignore this) |
485 | * @dentry: the dentry that points to the inode to sync | 505 | * @dentry: the dentry that points to the inode to sync |
486 | * | 506 | * |
507 | * The VFS will flush "normal" data for us. We only need to worry | ||
508 | * about metadata here. For journaled data, we just do a log flush | ||
509 | * as we can't avoid it. Otherwise we can just bale out if datasync | ||
510 | * is set. For stuffed inodes we must flush the log in order to | ||
511 | * ensure that all data is on disk. | ||
512 | * | ||
513 | * The call to write_inode_now() is there to write back metadata and | ||
514 | * the inode itself. It does also try and write the data, but thats | ||
515 | * (hopefully) a no-op due to the VFS having already called filemap_fdatawrite() | ||
516 | * for us. | ||
517 | * | ||
487 | * Returns: errno | 518 | * Returns: errno |
488 | */ | 519 | */ |
489 | 520 | ||
490 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | 521 | static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) |
491 | { | 522 | { |
492 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | 523 | struct inode *inode = dentry->d_inode; |
524 | int sync_state = inode->i_state & (I_DIRTY_SYNC|I_DIRTY_DATASYNC); | ||
525 | int ret = 0; | ||
493 | 526 | ||
494 | gfs2_log_flush(ip->i_gl->gl_sbd, ip->i_gl); | 527 | if (gfs2_is_jdata(GFS2_I(inode))) { |
528 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
529 | return 0; | ||
530 | } | ||
495 | 531 | ||
496 | return 0; | 532 | if (sync_state != 0) { |
533 | if (!datasync) | ||
534 | ret = write_inode_now(inode, 0); | ||
535 | |||
536 | if (gfs2_is_stuffed(GFS2_I(inode))) | ||
537 | gfs2_log_flush(GFS2_SB(inode), GFS2_I(inode)->i_gl); | ||
538 | } | ||
539 | |||
540 | return ret; | ||
497 | } | 541 | } |
498 | 542 | ||
499 | /** | 543 | /** |
@@ -515,7 +559,7 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) | |||
515 | 559 | ||
516 | if (!(fl->fl_flags & FL_POSIX)) | 560 | if (!(fl->fl_flags & FL_POSIX)) |
517 | return -ENOLCK; | 561 | return -ENOLCK; |
518 | if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 562 | if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
519 | return -ENOLCK; | 563 | return -ENOLCK; |
520 | 564 | ||
521 | if (sdp->sd_args.ar_localflocks) { | 565 | if (sdp->sd_args.ar_localflocks) { |
@@ -617,7 +661,7 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) | |||
617 | 661 | ||
618 | if (!(fl->fl_flags & FL_FLOCK)) | 662 | if (!(fl->fl_flags & FL_FLOCK)) |
619 | return -ENOLCK; | 663 | return -ENOLCK; |
620 | if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) | 664 | if ((ip->i_inode.i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) |
621 | return -ENOLCK; | 665 | return -ENOLCK; |
622 | 666 | ||
623 | if (sdp->sd_args.ar_localflocks) | 667 | if (sdp->sd_args.ar_localflocks) |
diff --git a/fs/gfs2/ops_file.h b/fs/gfs2/ops_file.h index ce319f89ec8e..7e5d8ec9c846 100644 --- a/fs/gfs2/ops_file.h +++ b/fs/gfs2/ops_file.h | |||
@@ -17,7 +17,7 @@ extern struct file gfs2_internal_file_sentinel; | |||
17 | extern int gfs2_internal_read(struct gfs2_inode *ip, | 17 | extern int gfs2_internal_read(struct gfs2_inode *ip, |
18 | struct file_ra_state *ra_state, | 18 | struct file_ra_state *ra_state, |
19 | char *buf, loff_t *pos, unsigned size); | 19 | char *buf, loff_t *pos, unsigned size); |
20 | 20 | extern void gfs2_set_inode_flags(struct inode *inode); | |
21 | extern const struct file_operations gfs2_file_fops; | 21 | extern const struct file_operations gfs2_file_fops; |
22 | extern const struct file_operations gfs2_dir_fops; | 22 | extern const struct file_operations gfs2_dir_fops; |
23 | 23 | ||
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 882873a6bd69..d14e139d2674 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -237,7 +237,7 @@ fail: | |||
237 | } | 237 | } |
238 | 238 | ||
239 | static struct inode *gfs2_lookup_root(struct super_block *sb, | 239 | static struct inode *gfs2_lookup_root(struct super_block *sb, |
240 | struct gfs2_inum *inum) | 240 | struct gfs2_inum_host *inum) |
241 | { | 241 | { |
242 | return gfs2_inode_lookup(sb, inum, DT_DIR); | 242 | return gfs2_inode_lookup(sb, inum, DT_DIR); |
243 | } | 243 | } |
@@ -246,7 +246,7 @@ static int init_sb(struct gfs2_sbd *sdp, int silent, int undo) | |||
246 | { | 246 | { |
247 | struct super_block *sb = sdp->sd_vfs; | 247 | struct super_block *sb = sdp->sd_vfs; |
248 | struct gfs2_holder sb_gh; | 248 | struct gfs2_holder sb_gh; |
249 | struct gfs2_inum *inum; | 249 | struct gfs2_inum_host *inum; |
250 | struct inode *inode; | 250 | struct inode *inode; |
251 | int error = 0; | 251 | int error = 0; |
252 | 252 | ||
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index ef6e5ed70e94..636dda4c7d38 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
@@ -59,7 +59,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry, | |||
59 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 59 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
60 | 60 | ||
61 | for (;;) { | 61 | for (;;) { |
62 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode); | 62 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFREG | mode, 0); |
63 | if (!IS_ERR(inode)) { | 63 | if (!IS_ERR(inode)) { |
64 | gfs2_trans_end(sdp); | 64 | gfs2_trans_end(sdp); |
65 | if (dip->i_alloc.al_rgd) | 65 | if (dip->i_alloc.al_rgd) |
@@ -144,7 +144,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
144 | int alloc_required; | 144 | int alloc_required; |
145 | int error; | 145 | int error; |
146 | 146 | ||
147 | if (S_ISDIR(ip->i_di.di_mode)) | 147 | if (S_ISDIR(inode->i_mode)) |
148 | return -EPERM; | 148 | return -EPERM; |
149 | 149 | ||
150 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); | 150 | gfs2_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, ghs); |
@@ -169,7 +169,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
169 | } | 169 | } |
170 | 170 | ||
171 | error = -EINVAL; | 171 | error = -EINVAL; |
172 | if (!dip->i_di.di_nlink) | 172 | if (!dip->i_inode.i_nlink) |
173 | goto out_gunlock; | 173 | goto out_gunlock; |
174 | error = -EFBIG; | 174 | error = -EFBIG; |
175 | if (dip->i_di.di_entries == (u32)-1) | 175 | if (dip->i_di.di_entries == (u32)-1) |
@@ -178,10 +178,10 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
178 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) | 178 | if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) |
179 | goto out_gunlock; | 179 | goto out_gunlock; |
180 | error = -EINVAL; | 180 | error = -EINVAL; |
181 | if (!ip->i_di.di_nlink) | 181 | if (!ip->i_inode.i_nlink) |
182 | goto out_gunlock; | 182 | goto out_gunlock; |
183 | error = -EMLINK; | 183 | error = -EMLINK; |
184 | if (ip->i_di.di_nlink == (u32)-1) | 184 | if (ip->i_inode.i_nlink == (u32)-1) |
185 | goto out_gunlock; | 185 | goto out_gunlock; |
186 | 186 | ||
187 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); | 187 | alloc_required = error = gfs2_diradd_alloc_required(dir, &dentry->d_name); |
@@ -196,8 +196,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
196 | if (error) | 196 | if (error) |
197 | goto out_alloc; | 197 | goto out_alloc; |
198 | 198 | ||
199 | error = gfs2_quota_check(dip, dip->i_di.di_uid, | 199 | error = gfs2_quota_check(dip, dip->i_inode.i_uid, dip->i_inode.i_gid); |
200 | dip->i_di.di_gid); | ||
201 | if (error) | 200 | if (error) |
202 | goto out_gunlock_q; | 201 | goto out_gunlock_q; |
203 | 202 | ||
@@ -220,7 +219,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, | |||
220 | } | 219 | } |
221 | 220 | ||
222 | error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, | 221 | error = gfs2_dir_add(dir, &dentry->d_name, &ip->i_num, |
223 | IF2DT(ip->i_di.di_mode)); | 222 | IF2DT(inode->i_mode)); |
224 | if (error) | 223 | if (error) |
225 | goto out_end_trans; | 224 | goto out_end_trans; |
226 | 225 | ||
@@ -326,7 +325,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
326 | 325 | ||
327 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 326 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
328 | 327 | ||
329 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO); | 328 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFLNK | S_IRWXUGO, 0); |
330 | if (IS_ERR(inode)) { | 329 | if (IS_ERR(inode)) { |
331 | gfs2_holder_uninit(ghs); | 330 | gfs2_holder_uninit(ghs); |
332 | return PTR_ERR(inode); | 331 | return PTR_ERR(inode); |
@@ -339,7 +338,7 @@ static int gfs2_symlink(struct inode *dir, struct dentry *dentry, | |||
339 | error = gfs2_meta_inode_buffer(ip, &dibh); | 338 | error = gfs2_meta_inode_buffer(ip, &dibh); |
340 | 339 | ||
341 | if (!gfs2_assert_withdraw(sdp, !error)) { | 340 | if (!gfs2_assert_withdraw(sdp, !error)) { |
342 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 341 | gfs2_dinode_out(ip, dibh->b_data); |
343 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, | 342 | memcpy(dibh->b_data + sizeof(struct gfs2_dinode), symname, |
344 | size); | 343 | size); |
345 | brelse(dibh); | 344 | brelse(dibh); |
@@ -379,7 +378,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
379 | 378 | ||
380 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 379 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
381 | 380 | ||
382 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode); | 381 | inode = gfs2_createi(ghs, &dentry->d_name, S_IFDIR | mode, 0); |
383 | if (IS_ERR(inode)) { | 382 | if (IS_ERR(inode)) { |
384 | gfs2_holder_uninit(ghs); | 383 | gfs2_holder_uninit(ghs); |
385 | return PTR_ERR(inode); | 384 | return PTR_ERR(inode); |
@@ -387,10 +386,9 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
387 | 386 | ||
388 | ip = ghs[1].gh_gl->gl_object; | 387 | ip = ghs[1].gh_gl->gl_object; |
389 | 388 | ||
390 | ip->i_di.di_nlink = 2; | 389 | ip->i_inode.i_nlink = 2; |
391 | ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); | 390 | ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode); |
392 | ip->i_di.di_flags |= GFS2_DIF_JDATA; | 391 | ip->i_di.di_flags |= GFS2_DIF_JDATA; |
393 | ip->i_di.di_payload_format = GFS2_FORMAT_DE; | ||
394 | ip->i_di.di_entries = 2; | 392 | ip->i_di.di_entries = 2; |
395 | 393 | ||
396 | error = gfs2_meta_inode_buffer(ip, &dibh); | 394 | error = gfs2_meta_inode_buffer(ip, &dibh); |
@@ -414,7 +412,7 @@ static int gfs2_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
414 | gfs2_inum_out(&dip->i_num, &dent->de_inum); | 412 | gfs2_inum_out(&dip->i_num, &dent->de_inum); |
415 | dent->de_type = cpu_to_be16(DT_DIR); | 413 | dent->de_type = cpu_to_be16(DT_DIR); |
416 | 414 | ||
417 | gfs2_dinode_out(&ip->i_di, di); | 415 | gfs2_dinode_out(ip, di); |
418 | 416 | ||
419 | brelse(dibh); | 417 | brelse(dibh); |
420 | } | 418 | } |
@@ -467,7 +465,7 @@ static int gfs2_rmdir(struct inode *dir, struct dentry *dentry) | |||
467 | 465 | ||
468 | if (ip->i_di.di_entries < 2) { | 466 | if (ip->i_di.di_entries < 2) { |
469 | if (gfs2_consist_inode(ip)) | 467 | if (gfs2_consist_inode(ip)) |
470 | gfs2_dinode_print(&ip->i_di); | 468 | gfs2_dinode_print(ip); |
471 | error = -EIO; | 469 | error = -EIO; |
472 | goto out_gunlock; | 470 | goto out_gunlock; |
473 | } | 471 | } |
@@ -504,47 +502,19 @@ out: | |||
504 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, | 502 | static int gfs2_mknod(struct inode *dir, struct dentry *dentry, int mode, |
505 | dev_t dev) | 503 | dev_t dev) |
506 | { | 504 | { |
507 | struct gfs2_inode *dip = GFS2_I(dir), *ip; | 505 | struct gfs2_inode *dip = GFS2_I(dir); |
508 | struct gfs2_sbd *sdp = GFS2_SB(dir); | 506 | struct gfs2_sbd *sdp = GFS2_SB(dir); |
509 | struct gfs2_holder ghs[2]; | 507 | struct gfs2_holder ghs[2]; |
510 | struct inode *inode; | 508 | struct inode *inode; |
511 | struct buffer_head *dibh; | ||
512 | u32 major = 0, minor = 0; | ||
513 | int error; | ||
514 | |||
515 | switch (mode & S_IFMT) { | ||
516 | case S_IFBLK: | ||
517 | case S_IFCHR: | ||
518 | major = MAJOR(dev); | ||
519 | minor = MINOR(dev); | ||
520 | break; | ||
521 | case S_IFIFO: | ||
522 | case S_IFSOCK: | ||
523 | break; | ||
524 | default: | ||
525 | return -EOPNOTSUPP; | ||
526 | }; | ||
527 | 509 | ||
528 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); | 510 | gfs2_holder_init(dip->i_gl, 0, 0, ghs); |
529 | 511 | ||
530 | inode = gfs2_createi(ghs, &dentry->d_name, mode); | 512 | inode = gfs2_createi(ghs, &dentry->d_name, mode, dev); |
531 | if (IS_ERR(inode)) { | 513 | if (IS_ERR(inode)) { |
532 | gfs2_holder_uninit(ghs); | 514 | gfs2_holder_uninit(ghs); |
533 | return PTR_ERR(inode); | 515 | return PTR_ERR(inode); |
534 | } | 516 | } |
535 | 517 | ||
536 | ip = ghs[1].gh_gl->gl_object; | ||
537 | |||
538 | ip->i_di.di_major = major; | ||
539 | ip->i_di.di_minor = minor; | ||
540 | |||
541 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
542 | |||
543 | if (!gfs2_assert_withdraw(sdp, !error)) { | ||
544 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | ||
545 | brelse(dibh); | ||
546 | } | ||
547 | |||
548 | gfs2_trans_end(sdp); | 518 | gfs2_trans_end(sdp); |
549 | if (dip->i_alloc.al_rgd) | 519 | if (dip->i_alloc.al_rgd) |
550 | gfs2_inplace_release(dip); | 520 | gfs2_inplace_release(dip); |
@@ -592,11 +562,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
592 | 562 | ||
593 | /* Make sure we aren't trying to move a dirctory into it's subdir */ | 563 | /* Make sure we aren't trying to move a dirctory into it's subdir */ |
594 | 564 | ||
595 | if (S_ISDIR(ip->i_di.di_mode) && odip != ndip) { | 565 | if (S_ISDIR(ip->i_inode.i_mode) && odip != ndip) { |
596 | dir_rename = 1; | 566 | dir_rename = 1; |
597 | 567 | ||
598 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, | 568 | error = gfs2_glock_nq_init(sdp->sd_rename_gl, LM_ST_EXCLUSIVE, 0, |
599 | LM_ST_EXCLUSIVE, 0, | ||
600 | &r_gh); | 569 | &r_gh); |
601 | if (error) | 570 | if (error) |
602 | goto out; | 571 | goto out; |
@@ -637,10 +606,10 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
637 | if (error) | 606 | if (error) |
638 | goto out_gunlock; | 607 | goto out_gunlock; |
639 | 608 | ||
640 | if (S_ISDIR(nip->i_di.di_mode)) { | 609 | if (S_ISDIR(nip->i_inode.i_mode)) { |
641 | if (nip->i_di.di_entries < 2) { | 610 | if (nip->i_di.di_entries < 2) { |
642 | if (gfs2_consist_inode(nip)) | 611 | if (gfs2_consist_inode(nip)) |
643 | gfs2_dinode_print(&nip->i_di); | 612 | gfs2_dinode_print(nip); |
644 | error = -EIO; | 613 | error = -EIO; |
645 | goto out_gunlock; | 614 | goto out_gunlock; |
646 | } | 615 | } |
@@ -666,7 +635,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
666 | }; | 635 | }; |
667 | 636 | ||
668 | if (odip != ndip) { | 637 | if (odip != ndip) { |
669 | if (!ndip->i_di.di_nlink) { | 638 | if (!ndip->i_inode.i_nlink) { |
670 | error = -EINVAL; | 639 | error = -EINVAL; |
671 | goto out_gunlock; | 640 | goto out_gunlock; |
672 | } | 641 | } |
@@ -674,8 +643,8 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
674 | error = -EFBIG; | 643 | error = -EFBIG; |
675 | goto out_gunlock; | 644 | goto out_gunlock; |
676 | } | 645 | } |
677 | if (S_ISDIR(ip->i_di.di_mode) && | 646 | if (S_ISDIR(ip->i_inode.i_mode) && |
678 | ndip->i_di.di_nlink == (u32)-1) { | 647 | ndip->i_inode.i_nlink == (u32)-1) { |
679 | error = -EMLINK; | 648 | error = -EMLINK; |
680 | goto out_gunlock; | 649 | goto out_gunlock; |
681 | } | 650 | } |
@@ -702,8 +671,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
702 | if (error) | 671 | if (error) |
703 | goto out_alloc; | 672 | goto out_alloc; |
704 | 673 | ||
705 | error = gfs2_quota_check(ndip, ndip->i_di.di_uid, | 674 | error = gfs2_quota_check(ndip, ndip->i_inode.i_uid, ndip->i_inode.i_gid); |
706 | ndip->i_di.di_gid); | ||
707 | if (error) | 675 | if (error) |
708 | goto out_gunlock_q; | 676 | goto out_gunlock_q; |
709 | 677 | ||
@@ -729,7 +697,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
729 | /* Remove the target file, if it exists */ | 697 | /* Remove the target file, if it exists */ |
730 | 698 | ||
731 | if (nip) { | 699 | if (nip) { |
732 | if (S_ISDIR(nip->i_di.di_mode)) | 700 | if (S_ISDIR(nip->i_inode.i_mode)) |
733 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); | 701 | error = gfs2_rmdiri(ndip, &ndentry->d_name, nip); |
734 | else { | 702 | else { |
735 | error = gfs2_dir_del(ndip, &ndentry->d_name); | 703 | error = gfs2_dir_del(ndip, &ndentry->d_name); |
@@ -760,9 +728,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
760 | error = gfs2_meta_inode_buffer(ip, &dibh); | 728 | error = gfs2_meta_inode_buffer(ip, &dibh); |
761 | if (error) | 729 | if (error) |
762 | goto out_end_trans; | 730 | goto out_end_trans; |
763 | ip->i_di.di_ctime = get_seconds(); | 731 | ip->i_inode.i_ctime.tv_sec = get_seconds(); |
764 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 732 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
765 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 733 | gfs2_dinode_out(ip, dibh->b_data); |
766 | brelse(dibh); | 734 | brelse(dibh); |
767 | } | 735 | } |
768 | 736 | ||
@@ -771,7 +739,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
771 | goto out_end_trans; | 739 | goto out_end_trans; |
772 | 740 | ||
773 | error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, | 741 | error = gfs2_dir_add(ndir, &ndentry->d_name, &ip->i_num, |
774 | IF2DT(ip->i_di.di_mode)); | 742 | IF2DT(ip->i_inode.i_mode)); |
775 | if (error) | 743 | if (error) |
776 | goto out_end_trans; | 744 | goto out_end_trans; |
777 | 745 | ||
@@ -867,6 +835,10 @@ static void *gfs2_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
867 | * @mask: | 835 | * @mask: |
868 | * @nd: passed from Linux VFS, ignored by us | 836 | * @nd: passed from Linux VFS, ignored by us |
869 | * | 837 | * |
838 | * This may be called from the VFS directly, or from within GFS2 with the | ||
839 | * inode locked, so we look to see if the glock is already locked and only | ||
840 | * lock the glock if its not already been done. | ||
841 | * | ||
870 | * Returns: errno | 842 | * Returns: errno |
871 | */ | 843 | */ |
872 | 844 | ||
@@ -875,15 +847,18 @@ static int gfs2_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
875 | struct gfs2_inode *ip = GFS2_I(inode); | 847 | struct gfs2_inode *ip = GFS2_I(inode); |
876 | struct gfs2_holder i_gh; | 848 | struct gfs2_holder i_gh; |
877 | int error; | 849 | int error; |
850 | int unlock = 0; | ||
878 | 851 | ||
879 | if (ip->i_vn == ip->i_gl->gl_vn) | 852 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) { |
880 | return generic_permission(inode, mask, gfs2_check_acl); | 853 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); |
854 | if (error) | ||
855 | return error; | ||
856 | unlock = 1; | ||
857 | } | ||
881 | 858 | ||
882 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | 859 | error = generic_permission(inode, mask, gfs2_check_acl); |
883 | if (!error) { | 860 | if (unlock) |
884 | error = generic_permission(inode, mask, gfs2_check_acl_locked); | ||
885 | gfs2_glock_dq_uninit(&i_gh); | 861 | gfs2_glock_dq_uninit(&i_gh); |
886 | } | ||
887 | 862 | ||
888 | return error; | 863 | return error; |
889 | } | 864 | } |
@@ -914,8 +889,8 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
914 | u32 ouid, ogid, nuid, ngid; | 889 | u32 ouid, ogid, nuid, ngid; |
915 | int error; | 890 | int error; |
916 | 891 | ||
917 | ouid = ip->i_di.di_uid; | 892 | ouid = inode->i_uid; |
918 | ogid = ip->i_di.di_gid; | 893 | ogid = inode->i_gid; |
919 | nuid = attr->ia_uid; | 894 | nuid = attr->ia_uid; |
920 | ngid = attr->ia_gid; | 895 | ngid = attr->ia_gid; |
921 | 896 | ||
@@ -946,10 +921,9 @@ static int setattr_chown(struct inode *inode, struct iattr *attr) | |||
946 | 921 | ||
947 | error = inode_setattr(inode, attr); | 922 | error = inode_setattr(inode, attr); |
948 | gfs2_assert_warn(sdp, !error); | 923 | gfs2_assert_warn(sdp, !error); |
949 | gfs2_inode_attr_out(ip); | ||
950 | 924 | ||
951 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 925 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
952 | gfs2_dinode_out(&ip->i_di, dibh->b_data); | 926 | gfs2_dinode_out(ip, dibh->b_data); |
953 | brelse(dibh); | 927 | brelse(dibh); |
954 | 928 | ||
955 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { | 929 | if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { |
@@ -1018,6 +992,12 @@ out: | |||
1018 | * @dentry: The dentry to stat | 992 | * @dentry: The dentry to stat |
1019 | * @stat: The inode's stats | 993 | * @stat: The inode's stats |
1020 | * | 994 | * |
995 | * This may be called from the VFS directly, or from within GFS2 with the | ||
996 | * inode locked, so we look to see if the glock is already locked and only | ||
997 | * lock the glock if its not already been done. Note that its the NFS | ||
998 | * readdirplus operation which causes this to be called (from filldir) | ||
999 | * with the glock already held. | ||
1000 | * | ||
1021 | * Returns: errno | 1001 | * Returns: errno |
1022 | */ | 1002 | */ |
1023 | 1003 | ||
@@ -1028,14 +1008,20 @@ static int gfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
1028 | struct gfs2_inode *ip = GFS2_I(inode); | 1008 | struct gfs2_inode *ip = GFS2_I(inode); |
1029 | struct gfs2_holder gh; | 1009 | struct gfs2_holder gh; |
1030 | int error; | 1010 | int error; |
1011 | int unlock = 0; | ||
1031 | 1012 | ||
1032 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); | 1013 | if (gfs2_glock_is_locked_by_me(ip->i_gl) == 0) { |
1033 | if (!error) { | 1014 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); |
1034 | generic_fillattr(inode, stat); | 1015 | if (error) |
1035 | gfs2_glock_dq_uninit(&gh); | 1016 | return error; |
1017 | unlock = 1; | ||
1036 | } | 1018 | } |
1037 | 1019 | ||
1038 | return error; | 1020 | generic_fillattr(inode, stat); |
1021 | if (unlock); | ||
1022 | gfs2_glock_dq_uninit(&gh); | ||
1023 | |||
1024 | return 0; | ||
1039 | } | 1025 | } |
1040 | 1026 | ||
1041 | static int gfs2_setxattr(struct dentry *dentry, const char *name, | 1027 | static int gfs2_setxattr(struct dentry *dentry, const char *name, |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 06f06f7773d0..7685b46f934b 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
@@ -138,16 +138,28 @@ static void gfs2_put_super(struct super_block *sb) | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /** | 140 | /** |
141 | * gfs2_write_super - disk commit all incore transactions | 141 | * gfs2_write_super |
142 | * @sb: the filesystem | 142 | * @sb: the superblock |
143 | * | 143 | * |
144 | * This function is called every time sync(2) is called. | ||
145 | * After this exits, all dirty buffers are synced. | ||
146 | */ | 144 | */ |
147 | 145 | ||
148 | static void gfs2_write_super(struct super_block *sb) | 146 | static void gfs2_write_super(struct super_block *sb) |
149 | { | 147 | { |
150 | gfs2_log_flush(sb->s_fs_info, NULL); | 148 | sb->s_dirt = 0; |
149 | } | ||
150 | |||
151 | /** | ||
152 | * gfs2_sync_fs - sync the filesystem | ||
153 | * @sb: the superblock | ||
154 | * | ||
155 | * Flushes the log to disk. | ||
156 | */ | ||
157 | static int gfs2_sync_fs(struct super_block *sb, int wait) | ||
158 | { | ||
159 | sb->s_dirt = 0; | ||
160 | if (wait) | ||
161 | gfs2_log_flush(sb->s_fs_info, NULL); | ||
162 | return 0; | ||
151 | } | 163 | } |
152 | 164 | ||
153 | /** | 165 | /** |
@@ -204,7 +216,7 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
204 | { | 216 | { |
205 | struct super_block *sb = dentry->d_inode->i_sb; | 217 | struct super_block *sb = dentry->d_inode->i_sb; |
206 | struct gfs2_sbd *sdp = sb->s_fs_info; | 218 | struct gfs2_sbd *sdp = sb->s_fs_info; |
207 | struct gfs2_statfs_change sc; | 219 | struct gfs2_statfs_change_host sc; |
208 | int error; | 220 | int error; |
209 | 221 | ||
210 | if (gfs2_tune_get(sdp, gt_statfs_slow)) | 222 | if (gfs2_tune_get(sdp, gt_statfs_slow)) |
@@ -282,8 +294,6 @@ static void gfs2_clear_inode(struct inode *inode) | |||
282 | */ | 294 | */ |
283 | if (inode->i_private) { | 295 | if (inode->i_private) { |
284 | struct gfs2_inode *ip = GFS2_I(inode); | 296 | struct gfs2_inode *ip = GFS2_I(inode); |
285 | gfs2_glock_inode_squish(inode); | ||
286 | gfs2_assert(inode->i_sb->s_fs_info, ip->i_gl->gl_state == LM_ST_UNLOCKED); | ||
287 | ip->i_gl->gl_object = NULL; | 297 | ip->i_gl->gl_object = NULL; |
288 | gfs2_glock_schedule_for_reclaim(ip->i_gl); | 298 | gfs2_glock_schedule_for_reclaim(ip->i_gl); |
289 | gfs2_glock_put(ip->i_gl); | 299 | gfs2_glock_put(ip->i_gl); |
@@ -384,7 +394,7 @@ static void gfs2_delete_inode(struct inode *inode) | |||
384 | if (!inode->i_private) | 394 | if (!inode->i_private) |
385 | goto out; | 395 | goto out; |
386 | 396 | ||
387 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &gh); | 397 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &gh); |
388 | if (unlikely(error)) { | 398 | if (unlikely(error)) { |
389 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); | 399 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
390 | goto out; | 400 | goto out; |
@@ -396,7 +406,7 @@ static void gfs2_delete_inode(struct inode *inode) | |||
396 | if (error) | 406 | if (error) |
397 | goto out_uninit; | 407 | goto out_uninit; |
398 | 408 | ||
399 | if (S_ISDIR(ip->i_di.di_mode) && | 409 | if (S_ISDIR(inode->i_mode) && |
400 | (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { | 410 | (ip->i_di.di_flags & GFS2_DIF_EXHASH)) { |
401 | error = gfs2_dir_exhash_dealloc(ip); | 411 | error = gfs2_dir_exhash_dealloc(ip); |
402 | if (error) | 412 | if (error) |
@@ -452,17 +462,18 @@ static void gfs2_destroy_inode(struct inode *inode) | |||
452 | } | 462 | } |
453 | 463 | ||
454 | struct super_operations gfs2_super_ops = { | 464 | struct super_operations gfs2_super_ops = { |
455 | .alloc_inode = gfs2_alloc_inode, | 465 | .alloc_inode = gfs2_alloc_inode, |
456 | .destroy_inode = gfs2_destroy_inode, | 466 | .destroy_inode = gfs2_destroy_inode, |
457 | .write_inode = gfs2_write_inode, | 467 | .write_inode = gfs2_write_inode, |
458 | .delete_inode = gfs2_delete_inode, | 468 | .delete_inode = gfs2_delete_inode, |
459 | .put_super = gfs2_put_super, | 469 | .put_super = gfs2_put_super, |
460 | .write_super = gfs2_write_super, | 470 | .write_super = gfs2_write_super, |
461 | .write_super_lockfs = gfs2_write_super_lockfs, | 471 | .sync_fs = gfs2_sync_fs, |
462 | .unlockfs = gfs2_unlockfs, | 472 | .write_super_lockfs = gfs2_write_super_lockfs, |
463 | .statfs = gfs2_statfs, | 473 | .unlockfs = gfs2_unlockfs, |
464 | .remount_fs = gfs2_remount_fs, | 474 | .statfs = gfs2_statfs, |
465 | .clear_inode = gfs2_clear_inode, | 475 | .remount_fs = gfs2_remount_fs, |
466 | .show_options = gfs2_show_options, | 476 | .clear_inode = gfs2_clear_inode, |
477 | .show_options = gfs2_show_options, | ||
467 | }; | 478 | }; |
468 | 479 | ||
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index 5453d2947ab3..45a5f11fc39a 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c | |||
@@ -76,7 +76,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | |||
76 | if (error) | 76 | if (error) |
77 | goto out; | 77 | goto out; |
78 | 78 | ||
79 | error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); | 79 | error = gfs2_quota_check(ip, ip->i_inode.i_uid, ip->i_inode.i_gid); |
80 | if (error) | 80 | if (error) |
81 | goto out_gunlock_q; | 81 | goto out_gunlock_q; |
82 | 82 | ||
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index a3deae7416c9..d0db881b55d2 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -452,19 +452,19 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
452 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 452 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
453 | return 0; | 453 | return 0; |
454 | 454 | ||
455 | error = qdsb_get(sdp, QUOTA_USER, ip->i_di.di_uid, CREATE, qd); | 455 | error = qdsb_get(sdp, QUOTA_USER, ip->i_inode.i_uid, CREATE, qd); |
456 | if (error) | 456 | if (error) |
457 | goto out; | 457 | goto out; |
458 | al->al_qd_num++; | 458 | al->al_qd_num++; |
459 | qd++; | 459 | qd++; |
460 | 460 | ||
461 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_di.di_gid, CREATE, qd); | 461 | error = qdsb_get(sdp, QUOTA_GROUP, ip->i_inode.i_gid, CREATE, qd); |
462 | if (error) | 462 | if (error) |
463 | goto out; | 463 | goto out; |
464 | al->al_qd_num++; | 464 | al->al_qd_num++; |
465 | qd++; | 465 | qd++; |
466 | 466 | ||
467 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_di.di_uid) { | 467 | if (uid != NO_QUOTA_CHANGE && uid != ip->i_inode.i_uid) { |
468 | error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd); | 468 | error = qdsb_get(sdp, QUOTA_USER, uid, CREATE, qd); |
469 | if (error) | 469 | if (error) |
470 | goto out; | 470 | goto out; |
@@ -472,7 +472,7 @@ int gfs2_quota_hold(struct gfs2_inode *ip, u32 uid, u32 gid) | |||
472 | qd++; | 472 | qd++; |
473 | } | 473 | } |
474 | 474 | ||
475 | if (gid != NO_QUOTA_CHANGE && gid != ip->i_di.di_gid) { | 475 | if (gid != NO_QUOTA_CHANGE && gid != ip->i_inode.i_gid) { |
476 | error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd); | 476 | error = qdsb_get(sdp, QUOTA_GROUP, gid, CREATE, qd); |
477 | if (error) | 477 | if (error) |
478 | goto out; | 478 | goto out; |
@@ -539,8 +539,7 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) | |||
539 | qc->qc_id = cpu_to_be32(qd->qd_id); | 539 | qc->qc_id = cpu_to_be32(qd->qd_id); |
540 | } | 540 | } |
541 | 541 | ||
542 | x = qc->qc_change; | 542 | x = be64_to_cpu(qc->qc_change) + change; |
543 | x = be64_to_cpu(x) + change; | ||
544 | qc->qc_change = cpu_to_be64(x); | 543 | qc->qc_change = cpu_to_be64(x); |
545 | 544 | ||
546 | spin_lock(&sdp->sd_quota_spin); | 545 | spin_lock(&sdp->sd_quota_spin); |
@@ -743,7 +742,7 @@ static int do_glock(struct gfs2_quota_data *qd, int force_refresh, | |||
743 | struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd; | 742 | struct gfs2_sbd *sdp = qd->qd_gl->gl_sbd; |
744 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); | 743 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); |
745 | struct gfs2_holder i_gh; | 744 | struct gfs2_holder i_gh; |
746 | struct gfs2_quota q; | 745 | struct gfs2_quota_host q; |
747 | char buf[sizeof(struct gfs2_quota)]; | 746 | char buf[sizeof(struct gfs2_quota)]; |
748 | struct file_ra_state ra_state; | 747 | struct file_ra_state ra_state; |
749 | int error; | 748 | int error; |
@@ -1103,7 +1102,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) | |||
1103 | 1102 | ||
1104 | for (y = 0; y < sdp->sd_qc_per_block && slot < sdp->sd_quota_slots; | 1103 | for (y = 0; y < sdp->sd_qc_per_block && slot < sdp->sd_quota_slots; |
1105 | y++, slot++) { | 1104 | y++, slot++) { |
1106 | struct gfs2_quota_change qc; | 1105 | struct gfs2_quota_change_host qc; |
1107 | struct gfs2_quota_data *qd; | 1106 | struct gfs2_quota_data *qd; |
1108 | 1107 | ||
1109 | gfs2_quota_change_in(&qc, bh->b_data + | 1108 | gfs2_quota_change_in(&qc, bh->b_data + |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 62cd223819b7..d0c806b85c86 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -132,10 +132,11 @@ void gfs2_revoke_clean(struct gfs2_sbd *sdp) | |||
132 | */ | 132 | */ |
133 | 133 | ||
134 | static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | 134 | static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, |
135 | struct gfs2_log_header *head) | 135 | struct gfs2_log_header_host *head) |
136 | { | 136 | { |
137 | struct buffer_head *bh; | 137 | struct buffer_head *bh; |
138 | struct gfs2_log_header lh; | 138 | struct gfs2_log_header_host lh; |
139 | const u32 nothing = 0; | ||
139 | u32 hash; | 140 | u32 hash; |
140 | int error; | 141 | int error; |
141 | 142 | ||
@@ -143,11 +144,11 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | |||
143 | if (error) | 144 | if (error) |
144 | return error; | 145 | return error; |
145 | 146 | ||
146 | memcpy(&lh, bh->b_data, sizeof(struct gfs2_log_header)); | 147 | hash = crc32_le((u32)~0, bh->b_data, sizeof(struct gfs2_log_header) - |
147 | lh.lh_hash = 0; | 148 | sizeof(u32)); |
148 | hash = gfs2_disk_hash((char *)&lh, sizeof(struct gfs2_log_header)); | 149 | hash = crc32_le(hash, (unsigned char const *)¬hing, sizeof(nothing)); |
150 | hash ^= (u32)~0; | ||
149 | gfs2_log_header_in(&lh, bh->b_data); | 151 | gfs2_log_header_in(&lh, bh->b_data); |
150 | |||
151 | brelse(bh); | 152 | brelse(bh); |
152 | 153 | ||
153 | if (lh.lh_header.mh_magic != GFS2_MAGIC || | 154 | if (lh.lh_header.mh_magic != GFS2_MAGIC || |
@@ -174,7 +175,7 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, | |||
174 | */ | 175 | */ |
175 | 176 | ||
176 | static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, | 177 | static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, |
177 | struct gfs2_log_header *head) | 178 | struct gfs2_log_header_host *head) |
178 | { | 179 | { |
179 | unsigned int orig_blk = *blk; | 180 | unsigned int orig_blk = *blk; |
180 | int error; | 181 | int error; |
@@ -205,10 +206,10 @@ static int find_good_lh(struct gfs2_jdesc *jd, unsigned int *blk, | |||
205 | * Returns: errno | 206 | * Returns: errno |
206 | */ | 207 | */ |
207 | 208 | ||
208 | static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 209 | static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
209 | { | 210 | { |
210 | unsigned int blk = head->lh_blkno; | 211 | unsigned int blk = head->lh_blkno; |
211 | struct gfs2_log_header lh; | 212 | struct gfs2_log_header_host lh; |
212 | int error; | 213 | int error; |
213 | 214 | ||
214 | for (;;) { | 215 | for (;;) { |
@@ -245,9 +246,9 @@ static int jhead_scan(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | |||
245 | * Returns: errno | 246 | * Returns: errno |
246 | */ | 247 | */ |
247 | 248 | ||
248 | int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 249 | int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
249 | { | 250 | { |
250 | struct gfs2_log_header lh_1, lh_m; | 251 | struct gfs2_log_header_host lh_1, lh_m; |
251 | u32 blk_1, blk_2, blk_m; | 252 | u32 blk_1, blk_2, blk_m; |
252 | int error; | 253 | int error; |
253 | 254 | ||
@@ -320,7 +321,7 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start, | |||
320 | length = be32_to_cpu(ld->ld_length); | 321 | length = be32_to_cpu(ld->ld_length); |
321 | 322 | ||
322 | if (be32_to_cpu(ld->ld_header.mh_type) == GFS2_METATYPE_LH) { | 323 | if (be32_to_cpu(ld->ld_header.mh_type) == GFS2_METATYPE_LH) { |
323 | struct gfs2_log_header lh; | 324 | struct gfs2_log_header_host lh; |
324 | error = get_log_header(jd, start, &lh); | 325 | error = get_log_header(jd, start, &lh); |
325 | if (!error) { | 326 | if (!error) { |
326 | gfs2_replay_incr_blk(sdp, &start); | 327 | gfs2_replay_incr_blk(sdp, &start); |
@@ -363,7 +364,7 @@ static int foreach_descriptor(struct gfs2_jdesc *jd, unsigned int start, | |||
363 | * Returns: errno | 364 | * Returns: errno |
364 | */ | 365 | */ |
365 | 366 | ||
366 | static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | 367 | static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head) |
367 | { | 368 | { |
368 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 369 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
369 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 370 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
@@ -425,7 +426,7 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd) | |||
425 | { | 426 | { |
426 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 427 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
427 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); | 428 | struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode); |
428 | struct gfs2_log_header head; | 429 | struct gfs2_log_header_host head; |
429 | struct gfs2_holder j_gh, ji_gh, t_gh; | 430 | struct gfs2_holder j_gh, ji_gh, t_gh; |
430 | unsigned long t; | 431 | unsigned long t; |
431 | int ro = 0; | 432 | int ro = 0; |
diff --git a/fs/gfs2/recovery.h b/fs/gfs2/recovery.h index 961feedf4d8b..f7235e61c723 100644 --- a/fs/gfs2/recovery.h +++ b/fs/gfs2/recovery.h | |||
@@ -26,7 +26,7 @@ int gfs2_revoke_check(struct gfs2_sbd *sdp, u64 blkno, unsigned int where); | |||
26 | void gfs2_revoke_clean(struct gfs2_sbd *sdp); | 26 | void gfs2_revoke_clean(struct gfs2_sbd *sdp); |
27 | 27 | ||
28 | int gfs2_find_jhead(struct gfs2_jdesc *jd, | 28 | int gfs2_find_jhead(struct gfs2_jdesc *jd, |
29 | struct gfs2_log_header *head); | 29 | struct gfs2_log_header_host *head); |
30 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); | 30 | int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); |
31 | void gfs2_check_journals(struct gfs2_sbd *sdp); | 31 | void gfs2_check_journals(struct gfs2_sbd *sdp); |
32 | 32 | ||
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index b261385c0065..ff0846528d54 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -253,7 +253,7 @@ void gfs2_rgrp_verify(struct gfs2_rgrpd *rgd) | |||
253 | 253 | ||
254 | } | 254 | } |
255 | 255 | ||
256 | static inline int rgrp_contains_block(struct gfs2_rindex *ri, u64 block) | 256 | static inline int rgrp_contains_block(struct gfs2_rindex_host *ri, u64 block) |
257 | { | 257 | { |
258 | u64 first = ri->ri_data0; | 258 | u64 first = ri->ri_data0; |
259 | u64 last = first + ri->ri_data; | 259 | u64 last = first + ri->ri_data; |
@@ -1217,7 +1217,7 @@ u64 gfs2_alloc_data(struct gfs2_inode *ip) | |||
1217 | al->al_alloced++; | 1217 | al->al_alloced++; |
1218 | 1218 | ||
1219 | gfs2_statfs_change(sdp, 0, -1, 0); | 1219 | gfs2_statfs_change(sdp, 0, -1, 0); |
1220 | gfs2_quota_change(ip, +1, ip->i_di.di_uid, ip->i_di.di_gid); | 1220 | gfs2_quota_change(ip, +1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1221 | 1221 | ||
1222 | spin_lock(&sdp->sd_rindex_spin); | 1222 | spin_lock(&sdp->sd_rindex_spin); |
1223 | rgd->rd_free_clone--; | 1223 | rgd->rd_free_clone--; |
@@ -1261,7 +1261,7 @@ u64 gfs2_alloc_meta(struct gfs2_inode *ip) | |||
1261 | al->al_alloced++; | 1261 | al->al_alloced++; |
1262 | 1262 | ||
1263 | gfs2_statfs_change(sdp, 0, -1, 0); | 1263 | gfs2_statfs_change(sdp, 0, -1, 0); |
1264 | gfs2_quota_change(ip, +1, ip->i_di.di_uid, ip->i_di.di_gid); | 1264 | gfs2_quota_change(ip, +1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1265 | gfs2_trans_add_unrevoke(sdp, block); | 1265 | gfs2_trans_add_unrevoke(sdp, block); |
1266 | 1266 | ||
1267 | spin_lock(&sdp->sd_rindex_spin); | 1267 | spin_lock(&sdp->sd_rindex_spin); |
@@ -1337,8 +1337,7 @@ void gfs2_free_data(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1337 | gfs2_trans_add_rg(rgd); | 1337 | gfs2_trans_add_rg(rgd); |
1338 | 1338 | ||
1339 | gfs2_statfs_change(sdp, 0, +blen, 0); | 1339 | gfs2_statfs_change(sdp, 0, +blen, 0); |
1340 | gfs2_quota_change(ip, -(s64)blen, | 1340 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1341 | ip->i_di.di_uid, ip->i_di.di_gid); | ||
1342 | } | 1341 | } |
1343 | 1342 | ||
1344 | /** | 1343 | /** |
@@ -1366,7 +1365,7 @@ void gfs2_free_meta(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
1366 | gfs2_trans_add_rg(rgd); | 1365 | gfs2_trans_add_rg(rgd); |
1367 | 1366 | ||
1368 | gfs2_statfs_change(sdp, 0, +blen, 0); | 1367 | gfs2_statfs_change(sdp, 0, +blen, 0); |
1369 | gfs2_quota_change(ip, -(s64)blen, ip->i_di.di_uid, ip->i_di.di_gid); | 1368 | gfs2_quota_change(ip, -(s64)blen, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1370 | gfs2_meta_wipe(ip, bstart, blen); | 1369 | gfs2_meta_wipe(ip, bstart, blen); |
1371 | } | 1370 | } |
1372 | 1371 | ||
@@ -1411,7 +1410,7 @@ static void gfs2_free_uninit_di(struct gfs2_rgrpd *rgd, u64 blkno) | |||
1411 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) | 1410 | void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip) |
1412 | { | 1411 | { |
1413 | gfs2_free_uninit_di(rgd, ip->i_num.no_addr); | 1412 | gfs2_free_uninit_di(rgd, ip->i_num.no_addr); |
1414 | gfs2_quota_change(ip, -1, ip->i_di.di_uid, ip->i_di.di_gid); | 1413 | gfs2_quota_change(ip, -1, ip->i_inode.i_uid, ip->i_inode.i_gid); |
1415 | gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); | 1414 | gfs2_meta_wipe(ip, ip->i_num.no_addr, 1); |
1416 | } | 1415 | } |
1417 | 1416 | ||
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 6a78b1b32e25..43a24f2e5905 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -97,7 +97,7 @@ void gfs2_tune_init(struct gfs2_tune *gt) | |||
97 | * changed. | 97 | * changed. |
98 | */ | 98 | */ |
99 | 99 | ||
100 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent) | 100 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent) |
101 | { | 101 | { |
102 | unsigned int x; | 102 | unsigned int x; |
103 | 103 | ||
@@ -180,6 +180,24 @@ static int end_bio_io_page(struct bio *bio, unsigned int bytes_done, int error) | |||
180 | return 0; | 180 | return 0; |
181 | } | 181 | } |
182 | 182 | ||
183 | /** | ||
184 | * gfs2_read_super - Read the gfs2 super block from disk | ||
185 | * @sb: The VFS super block | ||
186 | * @sector: The location of the super block | ||
187 | * | ||
188 | * This uses the bio functions to read the super block from disk | ||
189 | * because we want to be 100% sure that we never read cached data. | ||
190 | * A super block is read twice only during each GFS2 mount and is | ||
191 | * never written to by the filesystem. The first time its read no | ||
192 | * locks are held, and the only details which are looked at are those | ||
193 | * relating to the locking protocol. Once locking is up and working, | ||
194 | * the sb is read again under the lock to establish the location of | ||
195 | * the master directory (contains pointers to journals etc) and the | ||
196 | * root directory. | ||
197 | * | ||
198 | * Returns: A page containing the sb or NULL | ||
199 | */ | ||
200 | |||
183 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | 201 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector) |
184 | { | 202 | { |
185 | struct page *page; | 203 | struct page *page; |
@@ -199,7 +217,7 @@ struct page *gfs2_read_super(struct super_block *sb, sector_t sector) | |||
199 | return NULL; | 217 | return NULL; |
200 | } | 218 | } |
201 | 219 | ||
202 | bio->bi_sector = sector; | 220 | bio->bi_sector = sector * (sb->s_blocksize >> 9); |
203 | bio->bi_bdev = sb->s_bdev; | 221 | bio->bi_bdev = sb->s_bdev; |
204 | bio_add_page(bio, page, PAGE_SIZE, 0); | 222 | bio_add_page(bio, page, PAGE_SIZE, 0); |
205 | 223 | ||
@@ -508,7 +526,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
508 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); | 526 | struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode); |
509 | struct gfs2_glock *j_gl = ip->i_gl; | 527 | struct gfs2_glock *j_gl = ip->i_gl; |
510 | struct gfs2_holder t_gh; | 528 | struct gfs2_holder t_gh; |
511 | struct gfs2_log_header head; | 529 | struct gfs2_log_header_host head; |
512 | int error; | 530 | int error; |
513 | 531 | ||
514 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, | 532 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, |
@@ -517,7 +535,7 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp) | |||
517 | return error; | 535 | return error; |
518 | 536 | ||
519 | gfs2_meta_cache_flush(ip); | 537 | gfs2_meta_cache_flush(ip); |
520 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); | 538 | j_gl->gl_ops->go_inval(j_gl, DIO_METADATA); |
521 | 539 | ||
522 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); | 540 | error = gfs2_find_jhead(sdp->sd_jdesc, &head); |
523 | if (error) | 541 | if (error) |
@@ -587,9 +605,9 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
587 | int gfs2_statfs_init(struct gfs2_sbd *sdp) | 605 | int gfs2_statfs_init(struct gfs2_sbd *sdp) |
588 | { | 606 | { |
589 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 607 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
590 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 608 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
591 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 609 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
592 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 610 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
593 | struct buffer_head *m_bh, *l_bh; | 611 | struct buffer_head *m_bh, *l_bh; |
594 | struct gfs2_holder gh; | 612 | struct gfs2_holder gh; |
595 | int error; | 613 | int error; |
@@ -634,7 +652,7 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | |||
634 | s64 dinodes) | 652 | s64 dinodes) |
635 | { | 653 | { |
636 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 654 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
637 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 655 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
638 | struct buffer_head *l_bh; | 656 | struct buffer_head *l_bh; |
639 | int error; | 657 | int error; |
640 | 658 | ||
@@ -660,8 +678,8 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp) | |||
660 | { | 678 | { |
661 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 679 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
662 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 680 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
663 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 681 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
664 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 682 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
665 | struct gfs2_holder gh; | 683 | struct gfs2_holder gh; |
666 | struct buffer_head *m_bh, *l_bh; | 684 | struct buffer_head *m_bh, *l_bh; |
667 | int error; | 685 | int error; |
@@ -727,10 +745,10 @@ out: | |||
727 | * Returns: errno | 745 | * Returns: errno |
728 | */ | 746 | */ |
729 | 747 | ||
730 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | 748 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) |
731 | { | 749 | { |
732 | struct gfs2_statfs_change *m_sc = &sdp->sd_statfs_master; | 750 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
733 | struct gfs2_statfs_change *l_sc = &sdp->sd_statfs_local; | 751 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
734 | 752 | ||
735 | spin_lock(&sdp->sd_statfs_spin); | 753 | spin_lock(&sdp->sd_statfs_spin); |
736 | 754 | ||
@@ -760,7 +778,7 @@ int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | |||
760 | */ | 778 | */ |
761 | 779 | ||
762 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | 780 | static int statfs_slow_fill(struct gfs2_rgrpd *rgd, |
763 | struct gfs2_statfs_change *sc) | 781 | struct gfs2_statfs_change_host *sc) |
764 | { | 782 | { |
765 | gfs2_rgrp_verify(rgd); | 783 | gfs2_rgrp_verify(rgd); |
766 | sc->sc_total += rgd->rd_ri.ri_data; | 784 | sc->sc_total += rgd->rd_ri.ri_data; |
@@ -782,7 +800,7 @@ static int statfs_slow_fill(struct gfs2_rgrpd *rgd, | |||
782 | * Returns: errno | 800 | * Returns: errno |
783 | */ | 801 | */ |
784 | 802 | ||
785 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | 803 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc) |
786 | { | 804 | { |
787 | struct gfs2_holder ri_gh; | 805 | struct gfs2_holder ri_gh; |
788 | struct gfs2_rgrpd *rgd_next; | 806 | struct gfs2_rgrpd *rgd_next; |
@@ -792,7 +810,7 @@ int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc) | |||
792 | int done; | 810 | int done; |
793 | int error = 0, err; | 811 | int error = 0, err; |
794 | 812 | ||
795 | memset(sc, 0, sizeof(struct gfs2_statfs_change)); | 813 | memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); |
796 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); | 814 | gha = kcalloc(slots, sizeof(struct gfs2_holder), GFP_KERNEL); |
797 | if (!gha) | 815 | if (!gha) |
798 | return -ENOMEM; | 816 | return -ENOMEM; |
@@ -873,7 +891,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp, | |||
873 | struct gfs2_jdesc *jd; | 891 | struct gfs2_jdesc *jd; |
874 | struct lfcc *lfcc; | 892 | struct lfcc *lfcc; |
875 | LIST_HEAD(list); | 893 | LIST_HEAD(list); |
876 | struct gfs2_log_header lh; | 894 | struct gfs2_log_header_host lh; |
877 | int error; | 895 | int error; |
878 | 896 | ||
879 | error = gfs2_jindex_hold(sdp, &ji_gh); | 897 | error = gfs2_jindex_hold(sdp, &ji_gh); |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index 5bb443ae0f59..e590b2df11dc 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | void gfs2_tune_init(struct gfs2_tune *gt); | 15 | void gfs2_tune_init(struct gfs2_tune *gt); |
16 | 16 | ||
17 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb *sb, int silent); | 17 | int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent); |
18 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); | 18 | int gfs2_read_sb(struct gfs2_sbd *sdp, struct gfs2_glock *gl, int silent); |
19 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector); | 19 | struct page *gfs2_read_super(struct super_block *sb, sector_t sector); |
20 | 20 | ||
@@ -45,8 +45,8 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp); | |||
45 | void gfs2_statfs_change(struct gfs2_sbd *sdp, | 45 | void gfs2_statfs_change(struct gfs2_sbd *sdp, |
46 | s64 total, s64 free, s64 dinodes); | 46 | s64 total, s64 free, s64 dinodes); |
47 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); | 47 | int gfs2_statfs_sync(struct gfs2_sbd *sdp); |
48 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc); | 48 | int gfs2_statfs_i(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); |
49 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change *sc); | 49 | int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host *sc); |
50 | 50 | ||
51 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); | 51 | int gfs2_freeze_fs(struct gfs2_sbd *sdp); |
52 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); | 52 | void gfs2_unfreeze_fs(struct gfs2_sbd *sdp); |
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 0e0ec988f731..983eaf1e06be 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -426,9 +426,6 @@ static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ | |||
426 | } \ | 426 | } \ |
427 | TUNE_ATTR_2(name, name##_store) | 427 | TUNE_ATTR_2(name, name##_store) |
428 | 428 | ||
429 | TUNE_ATTR(ilimit, 0); | ||
430 | TUNE_ATTR(ilimit_tries, 0); | ||
431 | TUNE_ATTR(ilimit_min, 0); | ||
432 | TUNE_ATTR(demote_secs, 0); | 429 | TUNE_ATTR(demote_secs, 0); |
433 | TUNE_ATTR(incore_log_blocks, 0); | 430 | TUNE_ATTR(incore_log_blocks, 0); |
434 | TUNE_ATTR(log_flush_secs, 0); | 431 | TUNE_ATTR(log_flush_secs, 0); |
@@ -447,7 +444,6 @@ TUNE_ATTR(quota_simul_sync, 1); | |||
447 | TUNE_ATTR(quota_cache_secs, 1); | 444 | TUNE_ATTR(quota_cache_secs, 1); |
448 | TUNE_ATTR(max_atomic_write, 1); | 445 | TUNE_ATTR(max_atomic_write, 1); |
449 | TUNE_ATTR(stall_secs, 1); | 446 | TUNE_ATTR(stall_secs, 1); |
450 | TUNE_ATTR(entries_per_readdir, 1); | ||
451 | TUNE_ATTR(greedy_default, 1); | 447 | TUNE_ATTR(greedy_default, 1); |
452 | TUNE_ATTR(greedy_quantum, 1); | 448 | TUNE_ATTR(greedy_quantum, 1); |
453 | TUNE_ATTR(greedy_max, 1); | 449 | TUNE_ATTR(greedy_max, 1); |
@@ -459,9 +455,6 @@ TUNE_ATTR_DAEMON(quotad_secs, quotad_process); | |||
459 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); | 455 | TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); |
460 | 456 | ||
461 | static struct attribute *tune_attrs[] = { | 457 | static struct attribute *tune_attrs[] = { |
462 | &tune_attr_ilimit.attr, | ||
463 | &tune_attr_ilimit_tries.attr, | ||
464 | &tune_attr_ilimit_min.attr, | ||
465 | &tune_attr_demote_secs.attr, | 458 | &tune_attr_demote_secs.attr, |
466 | &tune_attr_incore_log_blocks.attr, | 459 | &tune_attr_incore_log_blocks.attr, |
467 | &tune_attr_log_flush_secs.attr, | 460 | &tune_attr_log_flush_secs.attr, |
@@ -478,7 +471,6 @@ static struct attribute *tune_attrs[] = { | |||
478 | &tune_attr_quota_cache_secs.attr, | 471 | &tune_attr_quota_cache_secs.attr, |
479 | &tune_attr_max_atomic_write.attr, | 472 | &tune_attr_max_atomic_write.attr, |
480 | &tune_attr_stall_secs.attr, | 473 | &tune_attr_stall_secs.attr, |
481 | &tune_attr_entries_per_readdir.attr, | ||
482 | &tune_attr_greedy_default.attr, | 474 | &tune_attr_greedy_default.attr, |
483 | &tune_attr_greedy_quantum.attr, | 475 | &tune_attr_greedy_quantum.attr, |
484 | &tune_attr_greedy_max.attr, | 476 | &tune_attr_greedy_max.attr, |
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c index 196c604faadc..e5707a9f78c2 100644 --- a/fs/gfs2/util.c +++ b/fs/gfs2/util.c | |||
@@ -23,9 +23,9 @@ | |||
23 | #include "lm.h" | 23 | #include "lm.h" |
24 | #include "util.h" | 24 | #include "util.h" |
25 | 25 | ||
26 | kmem_cache_t *gfs2_glock_cachep __read_mostly; | 26 | struct kmem_cache *gfs2_glock_cachep __read_mostly; |
27 | kmem_cache_t *gfs2_inode_cachep __read_mostly; | 27 | struct kmem_cache *gfs2_inode_cachep __read_mostly; |
28 | kmem_cache_t *gfs2_bufdata_cachep __read_mostly; | 28 | struct kmem_cache *gfs2_bufdata_cachep __read_mostly; |
29 | 29 | ||
30 | void gfs2_assert_i(struct gfs2_sbd *sdp) | 30 | void gfs2_assert_i(struct gfs2_sbd *sdp) |
31 | { | 31 | { |
diff --git a/fs/gfs2/util.h b/fs/gfs2/util.h index 76a50899fe9e..28938a46cf47 100644 --- a/fs/gfs2/util.h +++ b/fs/gfs2/util.h | |||
@@ -83,8 +83,7 @@ static inline int gfs2_meta_check_i(struct gfs2_sbd *sdp, | |||
83 | char *file, unsigned int line) | 83 | char *file, unsigned int line) |
84 | { | 84 | { |
85 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; | 85 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; |
86 | u32 magic = mh->mh_magic; | 86 | u32 magic = be32_to_cpu(mh->mh_magic); |
87 | magic = be32_to_cpu(magic); | ||
88 | if (unlikely(magic != GFS2_MAGIC)) | 87 | if (unlikely(magic != GFS2_MAGIC)) |
89 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, | 88 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, |
90 | file, line); | 89 | file, line); |
@@ -107,9 +106,8 @@ static inline int gfs2_metatype_check_i(struct gfs2_sbd *sdp, | |||
107 | char *file, unsigned int line) | 106 | char *file, unsigned int line) |
108 | { | 107 | { |
109 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; | 108 | struct gfs2_meta_header *mh = (struct gfs2_meta_header *)bh->b_data; |
110 | u32 magic = mh->mh_magic; | 109 | u32 magic = be32_to_cpu(mh->mh_magic); |
111 | u16 t = be32_to_cpu(mh->mh_type); | 110 | u16 t = be32_to_cpu(mh->mh_type); |
112 | magic = be32_to_cpu(magic); | ||
113 | if (unlikely(magic != GFS2_MAGIC)) | 111 | if (unlikely(magic != GFS2_MAGIC)) |
114 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, | 112 | return gfs2_meta_check_ii(sdp, bh, "magic number", function, |
115 | file, line); | 113 | file, line); |
@@ -146,9 +144,9 @@ int gfs2_io_error_bh_i(struct gfs2_sbd *sdp, struct buffer_head *bh, | |||
146 | gfs2_io_error_bh_i((sdp), (bh), __FUNCTION__, __FILE__, __LINE__); | 144 | gfs2_io_error_bh_i((sdp), (bh), __FUNCTION__, __FILE__, __LINE__); |
147 | 145 | ||
148 | 146 | ||
149 | extern kmem_cache_t *gfs2_glock_cachep; | 147 | extern struct kmem_cache *gfs2_glock_cachep; |
150 | extern kmem_cache_t *gfs2_inode_cachep; | 148 | extern struct kmem_cache *gfs2_inode_cachep; |
151 | extern kmem_cache_t *gfs2_bufdata_cachep; | 149 | extern struct kmem_cache *gfs2_bufdata_cachep; |
152 | 150 | ||
153 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, | 151 | static inline unsigned int gfs2_tune_get_i(struct gfs2_tune *gt, |
154 | unsigned int *p) | 152 | unsigned int *p) |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index d43b4fcc8ad3..a36987966004 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include "hfs_fs.h" | 24 | #include "hfs_fs.h" |
25 | #include "btree.h" | 25 | #include "btree.h" |
26 | 26 | ||
27 | static kmem_cache_t *hfs_inode_cachep; | 27 | static struct kmem_cache *hfs_inode_cachep; |
28 | 28 | ||
29 | MODULE_LICENSE("GPL"); | 29 | MODULE_LICENSE("GPL"); |
30 | 30 | ||
@@ -145,7 +145,7 @@ static struct inode *hfs_alloc_inode(struct super_block *sb) | |||
145 | { | 145 | { |
146 | struct hfs_inode_info *i; | 146 | struct hfs_inode_info *i; |
147 | 147 | ||
148 | i = kmem_cache_alloc(hfs_inode_cachep, SLAB_KERNEL); | 148 | i = kmem_cache_alloc(hfs_inode_cachep, GFP_KERNEL); |
149 | return i ? &i->vfs_inode : NULL; | 149 | return i ? &i->vfs_inode : NULL; |
150 | } | 150 | } |
151 | 151 | ||
@@ -390,11 +390,13 @@ static int hfs_fill_super(struct super_block *sb, void *data, int silent) | |||
390 | hfs_find_exit(&fd); | 390 | hfs_find_exit(&fd); |
391 | goto bail_no_root; | 391 | goto bail_no_root; |
392 | } | 392 | } |
393 | res = -EINVAL; | ||
393 | root_inode = hfs_iget(sb, &fd.search_key->cat, &rec); | 394 | root_inode = hfs_iget(sb, &fd.search_key->cat, &rec); |
394 | hfs_find_exit(&fd); | 395 | hfs_find_exit(&fd); |
395 | if (!root_inode) | 396 | if (!root_inode) |
396 | goto bail_no_root; | 397 | goto bail_no_root; |
397 | 398 | ||
399 | res = -ENOMEM; | ||
398 | sb->s_root = d_alloc_root(root_inode); | 400 | sb->s_root = d_alloc_root(root_inode); |
399 | if (!sb->s_root) | 401 | if (!sb->s_root) |
400 | goto bail_iput; | 402 | goto bail_iput; |
@@ -428,7 +430,7 @@ static struct file_system_type hfs_fs_type = { | |||
428 | .fs_flags = FS_REQUIRES_DEV, | 430 | .fs_flags = FS_REQUIRES_DEV, |
429 | }; | 431 | }; |
430 | 432 | ||
431 | static void hfs_init_once(void *p, kmem_cache_t *cachep, unsigned long flags) | 433 | static void hfs_init_once(void *p, struct kmem_cache *cachep, unsigned long flags) |
432 | { | 434 | { |
433 | struct hfs_inode_info *i = p; | 435 | struct hfs_inode_info *i = p; |
434 | 436 | ||
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 194eede52fa4..0f513c6bf843 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -434,13 +434,13 @@ MODULE_AUTHOR("Brad Boyer"); | |||
434 | MODULE_DESCRIPTION("Extended Macintosh Filesystem"); | 434 | MODULE_DESCRIPTION("Extended Macintosh Filesystem"); |
435 | MODULE_LICENSE("GPL"); | 435 | MODULE_LICENSE("GPL"); |
436 | 436 | ||
437 | static kmem_cache_t *hfsplus_inode_cachep; | 437 | static struct kmem_cache *hfsplus_inode_cachep; |
438 | 438 | ||
439 | static struct inode *hfsplus_alloc_inode(struct super_block *sb) | 439 | static struct inode *hfsplus_alloc_inode(struct super_block *sb) |
440 | { | 440 | { |
441 | struct hfsplus_inode_info *i; | 441 | struct hfsplus_inode_info *i; |
442 | 442 | ||
443 | i = kmem_cache_alloc(hfsplus_inode_cachep, SLAB_KERNEL); | 443 | i = kmem_cache_alloc(hfsplus_inode_cachep, GFP_KERNEL); |
444 | return i ? &i->vfs_inode : NULL; | 444 | return i ? &i->vfs_inode : NULL; |
445 | } | 445 | } |
446 | 446 | ||
@@ -467,7 +467,7 @@ static struct file_system_type hfsplus_fs_type = { | |||
467 | .fs_flags = FS_REQUIRES_DEV, | 467 | .fs_flags = FS_REQUIRES_DEV, |
468 | }; | 468 | }; |
469 | 469 | ||
470 | static void hfsplus_init_once(void *p, kmem_cache_t *cachep, unsigned long flags) | 470 | static void hfsplus_init_once(void *p, struct kmem_cache *cachep, unsigned long flags) |
471 | { | 471 | { |
472 | struct hfsplus_inode_info *i = p; | 472 | struct hfsplus_inode_info *i = p; |
473 | 473 | ||
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index ecc9180645ae..594f9c428fc2 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
@@ -84,7 +84,8 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
84 | } | 84 | } |
85 | if (!fno->dirflag) { | 85 | if (!fno->dirflag) { |
86 | e = 1; | 86 | e = 1; |
87 | hpfs_error(inode->i_sb, "not a directory, fnode %08x",inode->i_ino); | 87 | hpfs_error(inode->i_sb, "not a directory, fnode %08lx", |
88 | (unsigned long)inode->i_ino); | ||
88 | } | 89 | } |
89 | if (hpfs_inode->i_dno != fno->u.external[0].disk_secno) { | 90 | if (hpfs_inode->i_dno != fno->u.external[0].disk_secno) { |
90 | e = 1; | 91 | e = 1; |
@@ -144,8 +145,11 @@ static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
144 | } | 145 | } |
145 | if (de->first || de->last) { | 146 | if (de->first || de->last) { |
146 | if (hpfs_sb(inode->i_sb)->sb_chk) { | 147 | if (hpfs_sb(inode->i_sb)->sb_chk) { |
147 | if (de->first && !de->last && (de->namelen != 2 || de ->name[0] != 1 || de->name[1] != 1)) hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08x", old_pos); | 148 | if (de->first && !de->last && (de->namelen != 2 |
148 | if (de->last && (de->namelen != 1 || de ->name[0] != 255)) hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08x", old_pos); | 149 | || de ->name[0] != 1 || de->name[1] != 1)) |
150 | hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08lx", old_pos); | ||
151 | if (de->last && (de->namelen != 1 || de ->name[0] != 255)) | ||
152 | hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08lx", old_pos); | ||
149 | } | 153 | } |
150 | hpfs_brelse4(&qbh); | 154 | hpfs_brelse4(&qbh); |
151 | goto again; | 155 | goto again; |
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c index 229ff2fb1809..fe83c2b7d2d8 100644 --- a/fs/hpfs/dnode.c +++ b/fs/hpfs/dnode.c | |||
@@ -533,10 +533,13 @@ static void delete_empty_dnode(struct inode *i, dnode_secno dno) | |||
533 | struct buffer_head *bh; | 533 | struct buffer_head *bh; |
534 | struct dnode *d1; | 534 | struct dnode *d1; |
535 | struct quad_buffer_head qbh1; | 535 | struct quad_buffer_head qbh1; |
536 | if (hpfs_sb(i->i_sb)->sb_chk) if (up != i->i_ino) { | 536 | if (hpfs_sb(i->i_sb)->sb_chk) |
537 | hpfs_error(i->i_sb, "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08x", dno, up, i->i_ino); | 537 | if (up != i->i_ino) { |
538 | hpfs_error(i->i_sb, | ||
539 | "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08lx", | ||
540 | dno, up, (unsigned long)i->i_ino); | ||
538 | return; | 541 | return; |
539 | } | 542 | } |
540 | if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) { | 543 | if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) { |
541 | d1->up = up; | 544 | d1->up = up; |
542 | d1->root_dnode = 1; | 545 | d1->root_dnode = 1; |
@@ -851,7 +854,9 @@ struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp, | |||
851 | /* Going to the next dirent */ | 854 | /* Going to the next dirent */ |
852 | if ((d = de_next_de(de)) < dnode_end_de(dnode)) { | 855 | if ((d = de_next_de(de)) < dnode_end_de(dnode)) { |
853 | if (!(++*posp & 077)) { | 856 | if (!(++*posp & 077)) { |
854 | hpfs_error(inode->i_sb, "map_pos_dirent: pos crossed dnode boundary; pos = %08x", *posp); | 857 | hpfs_error(inode->i_sb, |
858 | "map_pos_dirent: pos crossed dnode boundary; pos = %08llx", | ||
859 | (unsigned long long)*posp); | ||
855 | goto bail; | 860 | goto bail; |
856 | } | 861 | } |
857 | /* We're going down the tree */ | 862 | /* We're going down the tree */ |
diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c index 66339dc030e4..547a8384571f 100644 --- a/fs/hpfs/ea.c +++ b/fs/hpfs/ea.c | |||
@@ -243,8 +243,9 @@ void hpfs_set_ea(struct inode *inode, struct fnode *fnode, char *key, char *data | |||
243 | fnode->ea_offs = 0xc4; | 243 | fnode->ea_offs = 0xc4; |
244 | } | 244 | } |
245 | if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) { | 245 | if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) { |
246 | hpfs_error(s, "fnode %08x: ea_offs == %03x, ea_size_s == %03x", | 246 | hpfs_error(s, "fnode %08lx: ea_offs == %03x, ea_size_s == %03x", |
247 | inode->i_ino, fnode->ea_offs, fnode->ea_size_s); | 247 | (unsigned long)inode->i_ino, |
248 | fnode->ea_offs, fnode->ea_size_s); | ||
248 | return; | 249 | return; |
249 | } | 250 | } |
250 | if ((fnode->ea_size_s || !fnode->ea_size_l) && | 251 | if ((fnode->ea_size_s || !fnode->ea_size_l) && |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 32ab51e42b96..1c07aa82d327 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
@@ -317,7 +317,8 @@ static inline struct hpfs_sb_info *hpfs_sb(struct super_block *sb) | |||
317 | 317 | ||
318 | /* super.c */ | 318 | /* super.c */ |
319 | 319 | ||
320 | void hpfs_error(struct super_block *, char *, ...); | 320 | void hpfs_error(struct super_block *, const char *, ...) |
321 | __attribute__((format (printf, 2, 3))); | ||
321 | int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *); | 322 | int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *); |
322 | unsigned hpfs_count_one_bitmap(struct super_block *, secno); | 323 | unsigned hpfs_count_one_bitmap(struct super_block *, secno); |
323 | 324 | ||
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 7faef8544f32..85d3e1d9ac00 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
@@ -251,7 +251,10 @@ void hpfs_write_inode_nolock(struct inode *i) | |||
251 | de->file_size = 0; | 251 | de->file_size = 0; |
252 | hpfs_mark_4buffers_dirty(&qbh); | 252 | hpfs_mark_4buffers_dirty(&qbh); |
253 | hpfs_brelse4(&qbh); | 253 | hpfs_brelse4(&qbh); |
254 | } else hpfs_error(i->i_sb, "directory %08x doesn't have '.' entry", i->i_ino); | 254 | } else |
255 | hpfs_error(i->i_sb, | ||
256 | "directory %08lx doesn't have '.' entry", | ||
257 | (unsigned long)i->i_ino); | ||
255 | } | 258 | } |
256 | mark_buffer_dirty(bh); | 259 | mark_buffer_dirty(bh); |
257 | brelse(bh); | 260 | brelse(bh); |
diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c index 0fecdac22e4e..c4724589b2eb 100644 --- a/fs/hpfs/map.c +++ b/fs/hpfs/map.c | |||
@@ -126,32 +126,40 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea | |||
126 | struct extended_attribute *ea; | 126 | struct extended_attribute *ea; |
127 | struct extended_attribute *ea_end; | 127 | struct extended_attribute *ea_end; |
128 | if (fnode->magic != FNODE_MAGIC) { | 128 | if (fnode->magic != FNODE_MAGIC) { |
129 | hpfs_error(s, "bad magic on fnode %08x", ino); | 129 | hpfs_error(s, "bad magic on fnode %08lx", |
130 | (unsigned long)ino); | ||
130 | goto bail; | 131 | goto bail; |
131 | } | 132 | } |
132 | if (!fnode->dirflag) { | 133 | if (!fnode->dirflag) { |
133 | if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != | 134 | if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != |
134 | (fnode->btree.internal ? 12 : 8)) { | 135 | (fnode->btree.internal ? 12 : 8)) { |
135 | hpfs_error(s, "bad number of nodes in fnode %08x", ino); | 136 | hpfs_error(s, |
137 | "bad number of nodes in fnode %08lx", | ||
138 | (unsigned long)ino); | ||
136 | goto bail; | 139 | goto bail; |
137 | } | 140 | } |
138 | if (fnode->btree.first_free != | 141 | if (fnode->btree.first_free != |
139 | 8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) { | 142 | 8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) { |
140 | hpfs_error(s, "bad first_free pointer in fnode %08x", ino); | 143 | hpfs_error(s, |
144 | "bad first_free pointer in fnode %08lx", | ||
145 | (unsigned long)ino); | ||
141 | goto bail; | 146 | goto bail; |
142 | } | 147 | } |
143 | } | 148 | } |
144 | if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 || | 149 | if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 || |
145 | (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) { | 150 | (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) { |
146 | hpfs_error(s, "bad EA info in fnode %08x: ea_offs == %04x ea_size_s == %04x", | 151 | hpfs_error(s, |
147 | ino, fnode->ea_offs, fnode->ea_size_s); | 152 | "bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x", |
153 | (unsigned long)ino, | ||
154 | fnode->ea_offs, fnode->ea_size_s); | ||
148 | goto bail; | 155 | goto bail; |
149 | } | 156 | } |
150 | ea = fnode_ea(fnode); | 157 | ea = fnode_ea(fnode); |
151 | ea_end = fnode_end_ea(fnode); | 158 | ea_end = fnode_end_ea(fnode); |
152 | while (ea != ea_end) { | 159 | while (ea != ea_end) { |
153 | if (ea > ea_end) { | 160 | if (ea > ea_end) { |
154 | hpfs_error(s, "bad EA in fnode %08x", ino); | 161 | hpfs_error(s, "bad EA in fnode %08lx", |
162 | (unsigned long)ino); | ||
155 | goto bail; | 163 | goto bail; |
156 | } | 164 | } |
157 | ea = next_ea(ea); | 165 | ea = next_ea(ea); |
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 450b5e0b4785..d4abc1a1d566 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
@@ -46,21 +46,17 @@ static void unmark_dirty(struct super_block *s) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | /* Filesystem error... */ | 48 | /* Filesystem error... */ |
49 | static char err_buf[1024]; | ||
49 | 50 | ||
50 | #define ERR_BUF_SIZE 1024 | 51 | void hpfs_error(struct super_block *s, const char *fmt, ...) |
51 | |||
52 | void hpfs_error(struct super_block *s, char *m,...) | ||
53 | { | 52 | { |
54 | char *buf; | 53 | va_list args; |
55 | va_list l; | 54 | |
56 | va_start(l, m); | 55 | va_start(args, fmt); |
57 | if (!(buf = kmalloc(ERR_BUF_SIZE, GFP_KERNEL))) | 56 | vsnprintf(err_buf, sizeof(err_buf), fmt, args); |
58 | printk("HPFS: No memory for error message '%s'\n",m); | 57 | va_end(args); |
59 | else if (vsprintf(buf, m, l) >= ERR_BUF_SIZE) | 58 | |
60 | printk("HPFS: Grrrr... Kernel memory corrupted ... going on, but it'll crash very soon :-(\n"); | 59 | printk("HPFS: filesystem error: %s", err_buf); |
61 | printk("HPFS: filesystem error: "); | ||
62 | if (buf) printk("%s", buf); | ||
63 | else printk("%s\n",m); | ||
64 | if (!hpfs_sb(s)->sb_was_error) { | 60 | if (!hpfs_sb(s)->sb_was_error) { |
65 | if (hpfs_sb(s)->sb_err == 2) { | 61 | if (hpfs_sb(s)->sb_err == 2) { |
66 | printk("; crashing the system because you wanted it\n"); | 62 | printk("; crashing the system because you wanted it\n"); |
@@ -76,7 +72,6 @@ void hpfs_error(struct super_block *s, char *m,...) | |||
76 | } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n"); | 72 | } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n"); |
77 | else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n"); | 73 | else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n"); |
78 | } else printk("\n"); | 74 | } else printk("\n"); |
79 | kfree(buf); | ||
80 | hpfs_sb(s)->sb_was_error = 1; | 75 | hpfs_sb(s)->sb_was_error = 1; |
81 | } | 76 | } |
82 | 77 | ||
@@ -160,12 +155,12 @@ static int hpfs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
160 | return 0; | 155 | return 0; |
161 | } | 156 | } |
162 | 157 | ||
163 | static kmem_cache_t * hpfs_inode_cachep; | 158 | static struct kmem_cache * hpfs_inode_cachep; |
164 | 159 | ||
165 | static struct inode *hpfs_alloc_inode(struct super_block *sb) | 160 | static struct inode *hpfs_alloc_inode(struct super_block *sb) |
166 | { | 161 | { |
167 | struct hpfs_inode_info *ei; | 162 | struct hpfs_inode_info *ei; |
168 | ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, SLAB_NOFS); | 163 | ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, GFP_NOFS); |
169 | if (!ei) | 164 | if (!ei) |
170 | return NULL; | 165 | return NULL; |
171 | ei->vfs_inode.i_version = 1; | 166 | ei->vfs_inode.i_version = 1; |
@@ -177,7 +172,7 @@ static void hpfs_destroy_inode(struct inode *inode) | |||
177 | kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode)); | 172 | kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode)); |
178 | } | 173 | } |
179 | 174 | ||
180 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 175 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
181 | { | 176 | { |
182 | struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; | 177 | struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo; |
183 | 178 | ||
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 0bea6a619e10..0706f5aac6a2 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -62,24 +62,19 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) | |||
62 | loff_t len, vma_len; | 62 | loff_t len, vma_len; |
63 | int ret; | 63 | int ret; |
64 | 64 | ||
65 | if (vma->vm_pgoff & (HPAGE_SIZE / PAGE_SIZE - 1)) | 65 | /* |
66 | return -EINVAL; | 66 | * vma alignment has already been checked by prepare_hugepage_range. |
67 | 67 | * If you add any error returns here, do so after setting VM_HUGETLB, | |
68 | if (vma->vm_start & ~HPAGE_MASK) | 68 | * so is_vm_hugetlb_page tests below unmap_region go the right way |
69 | return -EINVAL; | 69 | * when do_mmap_pgoff unwinds (may be important on powerpc and ia64). |
70 | 70 | */ | |
71 | if (vma->vm_end & ~HPAGE_MASK) | 71 | vma->vm_flags |= VM_HUGETLB | VM_RESERVED; |
72 | return -EINVAL; | 72 | vma->vm_ops = &hugetlb_vm_ops; |
73 | |||
74 | if (vma->vm_end - vma->vm_start < HPAGE_SIZE) | ||
75 | return -EINVAL; | ||
76 | 73 | ||
77 | vma_len = (loff_t)(vma->vm_end - vma->vm_start); | 74 | vma_len = (loff_t)(vma->vm_end - vma->vm_start); |
78 | 75 | ||
79 | mutex_lock(&inode->i_mutex); | 76 | mutex_lock(&inode->i_mutex); |
80 | file_accessed(file); | 77 | file_accessed(file); |
81 | vma->vm_flags |= VM_HUGETLB | VM_RESERVED; | ||
82 | vma->vm_ops = &hugetlb_vm_ops; | ||
83 | 78 | ||
84 | ret = -ENOMEM; | 79 | ret = -ENOMEM; |
85 | len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); | 80 | len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); |
@@ -518,7 +513,7 @@ static void hugetlbfs_inc_free_inodes(struct hugetlbfs_sb_info *sbinfo) | |||
518 | } | 513 | } |
519 | 514 | ||
520 | 515 | ||
521 | static kmem_cache_t *hugetlbfs_inode_cachep; | 516 | static struct kmem_cache *hugetlbfs_inode_cachep; |
522 | 517 | ||
523 | static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) | 518 | static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) |
524 | { | 519 | { |
@@ -527,7 +522,7 @@ static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) | |||
527 | 522 | ||
528 | if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo))) | 523 | if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo))) |
529 | return NULL; | 524 | return NULL; |
530 | p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL); | 525 | p = kmem_cache_alloc(hugetlbfs_inode_cachep, GFP_KERNEL); |
531 | if (unlikely(!p)) { | 526 | if (unlikely(!p)) { |
532 | hugetlbfs_inc_free_inodes(sbinfo); | 527 | hugetlbfs_inc_free_inodes(sbinfo); |
533 | return NULL; | 528 | return NULL; |
@@ -550,7 +545,7 @@ static const struct address_space_operations hugetlbfs_aops = { | |||
550 | }; | 545 | }; |
551 | 546 | ||
552 | 547 | ||
553 | static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 548 | static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
554 | { | 549 | { |
555 | struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; | 550 | struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo; |
556 | 551 | ||
diff --git a/fs/inode.c b/fs/inode.c index 26cdb115ce67..9ecccab7326d 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -97,7 +97,7 @@ static DEFINE_MUTEX(iprune_mutex); | |||
97 | */ | 97 | */ |
98 | struct inodes_stat_t inodes_stat; | 98 | struct inodes_stat_t inodes_stat; |
99 | 99 | ||
100 | static kmem_cache_t * inode_cachep __read_mostly; | 100 | static struct kmem_cache * inode_cachep __read_mostly; |
101 | 101 | ||
102 | static struct inode *alloc_inode(struct super_block *sb) | 102 | static struct inode *alloc_inode(struct super_block *sb) |
103 | { | 103 | { |
@@ -109,7 +109,7 @@ static struct inode *alloc_inode(struct super_block *sb) | |||
109 | if (sb->s_op->alloc_inode) | 109 | if (sb->s_op->alloc_inode) |
110 | inode = sb->s_op->alloc_inode(sb); | 110 | inode = sb->s_op->alloc_inode(sb); |
111 | else | 111 | else |
112 | inode = (struct inode *) kmem_cache_alloc(inode_cachep, SLAB_KERNEL); | 112 | inode = (struct inode *) kmem_cache_alloc(inode_cachep, GFP_KERNEL); |
113 | 113 | ||
114 | if (inode) { | 114 | if (inode) { |
115 | struct address_space * const mapping = &inode->i_data; | 115 | struct address_space * const mapping = &inode->i_data; |
@@ -209,7 +209,7 @@ void inode_init_once(struct inode *inode) | |||
209 | 209 | ||
210 | EXPORT_SYMBOL(inode_init_once); | 210 | EXPORT_SYMBOL(inode_init_once); |
211 | 211 | ||
212 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 212 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
213 | { | 213 | { |
214 | struct inode * inode = (struct inode *) foo; | 214 | struct inode * inode = (struct inode *) foo; |
215 | 215 | ||
@@ -1242,9 +1242,6 @@ EXPORT_SYMBOL(inode_needs_sync); | |||
1242 | */ | 1242 | */ |
1243 | #ifdef CONFIG_QUOTA | 1243 | #ifdef CONFIG_QUOTA |
1244 | 1244 | ||
1245 | /* Function back in dquot.c */ | ||
1246 | int remove_inode_dquot_ref(struct inode *, int, struct list_head *); | ||
1247 | |||
1248 | void remove_dquot_ref(struct super_block *sb, int type, | 1245 | void remove_dquot_ref(struct super_block *sb, int type, |
1249 | struct list_head *tofree_head) | 1246 | struct list_head *tofree_head) |
1250 | { | 1247 | { |
diff --git a/fs/inotify.c b/fs/inotify.c index 723836a1f718..f5099d86fd91 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/idr.h> | 27 | #include <linux/idr.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
30 | #include <linux/sched.h> | ||
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | #include <linux/list.h> | 32 | #include <linux/list.h> |
32 | #include <linux/writeback.h> | 33 | #include <linux/writeback.h> |
diff --git a/fs/inotify_user.c b/fs/inotify_user.c index 017cb0f134d6..e1956e6f116c 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c | |||
@@ -34,8 +34,8 @@ | |||
34 | 34 | ||
35 | #include <asm/ioctls.h> | 35 | #include <asm/ioctls.h> |
36 | 36 | ||
37 | static kmem_cache_t *watch_cachep __read_mostly; | 37 | static struct kmem_cache *watch_cachep __read_mostly; |
38 | static kmem_cache_t *event_cachep __read_mostly; | 38 | static struct kmem_cache *event_cachep __read_mostly; |
39 | 39 | ||
40 | static struct vfsmount *inotify_mnt __read_mostly; | 40 | static struct vfsmount *inotify_mnt __read_mostly; |
41 | 41 | ||
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index c34b862cdbf2..ea55b6c469ec 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -57,12 +57,12 @@ static void isofs_put_super(struct super_block *sb) | |||
57 | static void isofs_read_inode(struct inode *); | 57 | static void isofs_read_inode(struct inode *); |
58 | static int isofs_statfs (struct dentry *, struct kstatfs *); | 58 | static int isofs_statfs (struct dentry *, struct kstatfs *); |
59 | 59 | ||
60 | static kmem_cache_t *isofs_inode_cachep; | 60 | static struct kmem_cache *isofs_inode_cachep; |
61 | 61 | ||
62 | static struct inode *isofs_alloc_inode(struct super_block *sb) | 62 | static struct inode *isofs_alloc_inode(struct super_block *sb) |
63 | { | 63 | { |
64 | struct iso_inode_info *ei; | 64 | struct iso_inode_info *ei; |
65 | ei = kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL); | 65 | ei = kmem_cache_alloc(isofs_inode_cachep, GFP_KERNEL); |
66 | if (!ei) | 66 | if (!ei) |
67 | return NULL; | 67 | return NULL; |
68 | return &ei->vfs_inode; | 68 | return &ei->vfs_inode; |
@@ -73,7 +73,7 @@ static void isofs_destroy_inode(struct inode *inode) | |||
73 | kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); | 73 | kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); |
74 | } | 74 | } |
75 | 75 | ||
76 | static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) | 76 | static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) |
77 | { | 77 | { |
78 | struct iso_inode_info *ei = foo; | 78 | struct iso_inode_info *ei = foo; |
79 | 79 | ||
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index b85c686b60db..10fff9443938 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/suspend.h> | 34 | #include <linux/freezer.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/poison.h> | 37 | #include <linux/poison.h> |
@@ -1630,7 +1630,7 @@ void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) | |||
1630 | #define JBD_MAX_SLABS 5 | 1630 | #define JBD_MAX_SLABS 5 |
1631 | #define JBD_SLAB_INDEX(size) (size >> 11) | 1631 | #define JBD_SLAB_INDEX(size) (size >> 11) |
1632 | 1632 | ||
1633 | static kmem_cache_t *jbd_slab[JBD_MAX_SLABS]; | 1633 | static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; |
1634 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { | 1634 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { |
1635 | "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" | 1635 | "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" |
1636 | }; | 1636 | }; |
@@ -1693,7 +1693,7 @@ void jbd_slab_free(void *ptr, size_t size) | |||
1693 | /* | 1693 | /* |
1694 | * Journal_head storage management | 1694 | * Journal_head storage management |
1695 | */ | 1695 | */ |
1696 | static kmem_cache_t *journal_head_cache; | 1696 | static struct kmem_cache *journal_head_cache; |
1697 | #ifdef CONFIG_JBD_DEBUG | 1697 | #ifdef CONFIG_JBD_DEBUG |
1698 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); | 1698 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); |
1699 | #endif | 1699 | #endif |
@@ -1996,7 +1996,7 @@ static void __exit remove_jbd_proc_entry(void) | |||
1996 | 1996 | ||
1997 | #endif | 1997 | #endif |
1998 | 1998 | ||
1999 | kmem_cache_t *jbd_handle_cache; | 1999 | struct kmem_cache *jbd_handle_cache; |
2000 | 2000 | ||
2001 | static int __init journal_init_handle_cache(void) | 2001 | static int __init journal_init_handle_cache(void) |
2002 | { | 2002 | { |
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index c532429d8d9b..d204ab394f36 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
@@ -70,8 +70,8 @@ | |||
70 | #include <linux/init.h> | 70 | #include <linux/init.h> |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | static kmem_cache_t *revoke_record_cache; | 73 | static struct kmem_cache *revoke_record_cache; |
74 | static kmem_cache_t *revoke_table_cache; | 74 | static struct kmem_cache *revoke_table_cache; |
75 | 75 | ||
76 | /* Each revoke record represents one single revoked block. During | 76 | /* Each revoke record represents one single revoked block. During |
77 | journal replay, this involves recording the transaction ID of the | 77 | journal replay, this involves recording the transaction ID of the |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 4f82bcd63e48..d38e0d575e48 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | 29 | ||
30 | static void __journal_temp_unlink_buffer(struct journal_head *jh); | ||
31 | |||
30 | /* | 32 | /* |
31 | * get_transaction: obtain a new transaction_t object. | 33 | * get_transaction: obtain a new transaction_t object. |
32 | * | 34 | * |
@@ -1499,7 +1501,7 @@ __blist_del_buffer(struct journal_head **list, struct journal_head *jh) | |||
1499 | * | 1501 | * |
1500 | * Called under j_list_lock. The journal may not be locked. | 1502 | * Called under j_list_lock. The journal may not be locked. |
1501 | */ | 1503 | */ |
1502 | void __journal_temp_unlink_buffer(struct journal_head *jh) | 1504 | static void __journal_temp_unlink_buffer(struct journal_head *jh) |
1503 | { | 1505 | { |
1504 | struct journal_head **list = NULL; | 1506 | struct journal_head **list = NULL; |
1505 | transaction_t *transaction; | 1507 | transaction_t *transaction; |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 70b2ae1ef281..6bd8005e3d34 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -248,8 +248,12 @@ write_out_data: | |||
248 | bufs = 0; | 248 | bufs = 0; |
249 | goto write_out_data; | 249 | goto write_out_data; |
250 | } | 250 | } |
251 | } | 251 | } else if (!locked && buffer_locked(bh)) { |
252 | else { | 252 | __jbd2_journal_file_buffer(jh, commit_transaction, |
253 | BJ_Locked); | ||
254 | jbd_unlock_bh_state(bh); | ||
255 | put_bh(bh); | ||
256 | } else { | ||
253 | BUFFER_TRACE(bh, "writeout complete: unfile"); | 257 | BUFFER_TRACE(bh, "writeout complete: unfile"); |
254 | __jbd2_journal_unfile_buffer(jh); | 258 | __jbd2_journal_unfile_buffer(jh); |
255 | jbd_unlock_bh_state(bh); | 259 | jbd_unlock_bh_state(bh); |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index c60f378b0f76..44fc32bfd7f1 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
32 | #include <linux/init.h> | 32 | #include <linux/init.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/suspend.h> | 34 | #include <linux/freezer.h> |
35 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/poison.h> | 37 | #include <linux/poison.h> |
@@ -1641,7 +1641,7 @@ void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry) | |||
1641 | #define JBD_MAX_SLABS 5 | 1641 | #define JBD_MAX_SLABS 5 |
1642 | #define JBD_SLAB_INDEX(size) (size >> 11) | 1642 | #define JBD_SLAB_INDEX(size) (size >> 11) |
1643 | 1643 | ||
1644 | static kmem_cache_t *jbd_slab[JBD_MAX_SLABS]; | 1644 | static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; |
1645 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { | 1645 | static const char *jbd_slab_names[JBD_MAX_SLABS] = { |
1646 | "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k" | 1646 | "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k" |
1647 | }; | 1647 | }; |
@@ -1704,7 +1704,7 @@ void jbd2_slab_free(void *ptr, size_t size) | |||
1704 | /* | 1704 | /* |
1705 | * Journal_head storage management | 1705 | * Journal_head storage management |
1706 | */ | 1706 | */ |
1707 | static kmem_cache_t *jbd2_journal_head_cache; | 1707 | static struct kmem_cache *jbd2_journal_head_cache; |
1708 | #ifdef CONFIG_JBD_DEBUG | 1708 | #ifdef CONFIG_JBD_DEBUG |
1709 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); | 1709 | static atomic_t nr_journal_heads = ATOMIC_INIT(0); |
1710 | #endif | 1710 | #endif |
@@ -2007,7 +2007,7 @@ static void __exit jbd2_remove_jbd_proc_entry(void) | |||
2007 | 2007 | ||
2008 | #endif | 2008 | #endif |
2009 | 2009 | ||
2010 | kmem_cache_t *jbd2_handle_cache; | 2010 | struct kmem_cache *jbd2_handle_cache; |
2011 | 2011 | ||
2012 | static int __init journal_init_handle_cache(void) | 2012 | static int __init journal_init_handle_cache(void) |
2013 | { | 2013 | { |
diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index 380d19917f37..f506646ad0ff 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c | |||
@@ -70,8 +70,8 @@ | |||
70 | #include <linux/init.h> | 70 | #include <linux/init.h> |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | static kmem_cache_t *jbd2_revoke_record_cache; | 73 | static struct kmem_cache *jbd2_revoke_record_cache; |
74 | static kmem_cache_t *jbd2_revoke_table_cache; | 74 | static struct kmem_cache *jbd2_revoke_table_cache; |
75 | 75 | ||
76 | /* Each revoke record represents one single revoked block. During | 76 | /* Each revoke record represents one single revoked block. During |
77 | journal replay, this involves recording the transaction ID of the | 77 | journal replay, this involves recording the transaction ID of the |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index c051a94c8a97..3a8700153cb0 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
29 | 29 | ||
30 | static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh); | ||
31 | |||
30 | /* | 32 | /* |
31 | * jbd2_get_transaction: obtain a new transaction_t object. | 33 | * jbd2_get_transaction: obtain a new transaction_t object. |
32 | * | 34 | * |
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c index 3f7899ea4cba..9f15bce92022 100644 --- a/fs/jffs/inode-v23.c +++ b/fs/jffs/inode-v23.c | |||
@@ -61,8 +61,8 @@ static const struct file_operations jffs_dir_operations; | |||
61 | static struct inode_operations jffs_dir_inode_operations; | 61 | static struct inode_operations jffs_dir_inode_operations; |
62 | static const struct address_space_operations jffs_address_operations; | 62 | static const struct address_space_operations jffs_address_operations; |
63 | 63 | ||
64 | kmem_cache_t *node_cache = NULL; | 64 | struct kmem_cache *node_cache = NULL; |
65 | kmem_cache_t *fm_cache = NULL; | 65 | struct kmem_cache *fm_cache = NULL; |
66 | 66 | ||
67 | /* Called by the VFS at mount time to initialize the whole file system. */ | 67 | /* Called by the VFS at mount time to initialize the whole file system. */ |
68 | static int jffs_fill_super(struct super_block *sb, void *data, int silent) | 68 | static int jffs_fill_super(struct super_block *sb, void *data, int silent) |
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index 4a543e114970..d0e783f199ea 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/smp_lock.h> | 66 | #include <linux/smp_lock.h> |
67 | #include <linux/time.h> | 67 | #include <linux/time.h> |
68 | #include <linux/ctype.h> | 68 | #include <linux/ctype.h> |
69 | #include <linux/freezer.h> | ||
69 | 70 | ||
70 | #include "intrep.h" | 71 | #include "intrep.h" |
71 | #include "jffs_fm.h" | 72 | #include "jffs_fm.h" |
@@ -591,7 +592,7 @@ jffs_add_virtual_root(struct jffs_control *c) | |||
591 | D2(printk("jffs_add_virtual_root(): " | 592 | D2(printk("jffs_add_virtual_root(): " |
592 | "Creating a virtual root directory.\n")); | 593 | "Creating a virtual root directory.\n")); |
593 | 594 | ||
594 | if (!(root = kmalloc(sizeof(struct jffs_file), GFP_KERNEL))) { | 595 | if (!(root = kzalloc(sizeof(struct jffs_file), GFP_KERNEL))) { |
595 | return -ENOMEM; | 596 | return -ENOMEM; |
596 | } | 597 | } |
597 | no_jffs_file++; | 598 | no_jffs_file++; |
@@ -603,7 +604,6 @@ jffs_add_virtual_root(struct jffs_control *c) | |||
603 | DJM(no_jffs_node++); | 604 | DJM(no_jffs_node++); |
604 | memset(node, 0, sizeof(struct jffs_node)); | 605 | memset(node, 0, sizeof(struct jffs_node)); |
605 | node->ino = JFFS_MIN_INO; | 606 | node->ino = JFFS_MIN_INO; |
606 | memset(root, 0, sizeof(struct jffs_file)); | ||
607 | root->ino = JFFS_MIN_INO; | 607 | root->ino = JFFS_MIN_INO; |
608 | root->mode = S_IFDIR | S_IRWXU | S_IRGRP | 608 | root->mode = S_IFDIR | S_IRWXU | S_IRGRP |
609 | | S_IXGRP | S_IROTH | S_IXOTH; | 609 | | S_IXGRP | S_IROTH | S_IXOTH; |
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c index 29b68d939bd9..077258b2103e 100644 --- a/fs/jffs/jffs_fm.c +++ b/fs/jffs/jffs_fm.c | |||
@@ -29,8 +29,8 @@ static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset); | |||
29 | static struct jffs_fm *jffs_alloc_fm(void); | 29 | static struct jffs_fm *jffs_alloc_fm(void); |
30 | static void jffs_free_fm(struct jffs_fm *n); | 30 | static void jffs_free_fm(struct jffs_fm *n); |
31 | 31 | ||
32 | extern kmem_cache_t *fm_cache; | 32 | extern struct kmem_cache *fm_cache; |
33 | extern kmem_cache_t *node_cache; | 33 | extern struct kmem_cache *node_cache; |
34 | 34 | ||
35 | #if CONFIG_JFFS_FS_VERBOSE > 0 | 35 | #if CONFIG_JFFS_FS_VERBOSE > 0 |
36 | void | 36 | void |
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 0ae3cd10702c..73f0d60f73a5 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/sched.h> | ||
14 | #include <linux/time.h> | 15 | #include <linux/time.h> |
15 | #include <linux/crc32.h> | 16 | #include <linux/crc32.h> |
16 | #include <linux/jffs2.h> | 17 | #include <linux/jffs2.h> |
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index ff2a872e80e7..6eb3daebd563 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
17 | #include <linux/completion.h> | 17 | #include <linux/completion.h> |
18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
19 | #include <linux/freezer.h> | ||
19 | #include "nodelist.h" | 20 | #include "nodelist.h" |
20 | 21 | ||
21 | 22 | ||
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c index 33f291005012..83f9881ec4cc 100644 --- a/fs/jffs2/malloc.c +++ b/fs/jffs2/malloc.c | |||
@@ -19,16 +19,16 @@ | |||
19 | 19 | ||
20 | /* These are initialised to NULL in the kernel startup code. | 20 | /* These are initialised to NULL in the kernel startup code. |
21 | If you're porting to other operating systems, beware */ | 21 | If you're porting to other operating systems, beware */ |
22 | static kmem_cache_t *full_dnode_slab; | 22 | static struct kmem_cache *full_dnode_slab; |
23 | static kmem_cache_t *raw_dirent_slab; | 23 | static struct kmem_cache *raw_dirent_slab; |
24 | static kmem_cache_t *raw_inode_slab; | 24 | static struct kmem_cache *raw_inode_slab; |
25 | static kmem_cache_t *tmp_dnode_info_slab; | 25 | static struct kmem_cache *tmp_dnode_info_slab; |
26 | static kmem_cache_t *raw_node_ref_slab; | 26 | static struct kmem_cache *raw_node_ref_slab; |
27 | static kmem_cache_t *node_frag_slab; | 27 | static struct kmem_cache *node_frag_slab; |
28 | static kmem_cache_t *inode_cache_slab; | 28 | static struct kmem_cache *inode_cache_slab; |
29 | #ifdef CONFIG_JFFS2_FS_XATTR | 29 | #ifdef CONFIG_JFFS2_FS_XATTR |
30 | static kmem_cache_t *xattr_datum_cache; | 30 | static struct kmem_cache *xattr_datum_cache; |
31 | static kmem_cache_t *xattr_ref_cache; | 31 | static struct kmem_cache *xattr_ref_cache; |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | int __init jffs2_create_slab_caches(void) | 34 | int __init jffs2_create_slab_caches(void) |
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index bc4b8106a490..7deb78254021 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
@@ -28,12 +28,12 @@ | |||
28 | 28 | ||
29 | static void jffs2_put_super(struct super_block *); | 29 | static void jffs2_put_super(struct super_block *); |
30 | 30 | ||
31 | static kmem_cache_t *jffs2_inode_cachep; | 31 | static struct kmem_cache *jffs2_inode_cachep; |
32 | 32 | ||
33 | static struct inode *jffs2_alloc_inode(struct super_block *sb) | 33 | static struct inode *jffs2_alloc_inode(struct super_block *sb) |
34 | { | 34 | { |
35 | struct jffs2_inode_info *ei; | 35 | struct jffs2_inode_info *ei; |
36 | ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, SLAB_KERNEL); | 36 | ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, GFP_KERNEL); |
37 | if (!ei) | 37 | if (!ei) |
38 | return NULL; | 38 | return NULL; |
39 | return &ei->vfs_inode; | 39 | return &ei->vfs_inode; |
@@ -44,7 +44,7 @@ static void jffs2_destroy_inode(struct inode *inode) | |||
44 | kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); | 44 | kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); |
45 | } | 45 | } |
46 | 46 | ||
47 | static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 47 | static void jffs2_i_init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
48 | { | 48 | { |
49 | struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; | 49 | struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo; |
50 | 50 | ||
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index b9b700730dfe..70707309dfa1 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/crc32.h> | 19 | #include <linux/crc32.h> |
20 | #include <linux/mtd/nand.h> | 20 | #include <linux/mtd/nand.h> |
21 | #include <linux/jiffies.h> | 21 | #include <linux/jiffies.h> |
22 | #include <linux/sched.h> | ||
22 | 23 | ||
23 | #include "nodelist.h" | 24 | #include "nodelist.h" |
24 | 25 | ||
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index 37db52488262..ed814b1ff4d9 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/ctype.h> | 9 | #include <linux/ctype.h> |
10 | #include <linux/capability.h> | 10 | #include <linux/capability.h> |
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
12 | #include <linux/sched.h> | ||
12 | #include <asm/current.h> | 13 | #include <asm/current.h> |
13 | #include <asm/uaccess.h> | 14 | #include <asm/uaccess.h> |
14 | 15 | ||
diff --git a/fs/jfs/jfs_filsys.h b/fs/jfs/jfs_filsys.h index 9901928668cf..eb550b339bb8 100644 --- a/fs/jfs/jfs_filsys.h +++ b/fs/jfs/jfs_filsys.h | |||
@@ -81,7 +81,7 @@ | |||
81 | #define JFS_SWAP_BYTES 0x00100000 /* running on big endian computer */ | 81 | #define JFS_SWAP_BYTES 0x00100000 /* running on big endian computer */ |
82 | 82 | ||
83 | /* Directory index */ | 83 | /* Directory index */ |
84 | #define JFS_DIR_INDEX 0x00200000 /* Persistant index for */ | 84 | #define JFS_DIR_INDEX 0x00200000 /* Persistent index for */ |
85 | /* directory entries */ | 85 | /* directory entries */ |
86 | 86 | ||
87 | 87 | ||
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index b89c9aba0466..5065baa530b6 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c | |||
@@ -67,7 +67,7 @@ | |||
67 | #include <linux/kthread.h> | 67 | #include <linux/kthread.h> |
68 | #include <linux/buffer_head.h> /* for sync_blockdev() */ | 68 | #include <linux/buffer_head.h> /* for sync_blockdev() */ |
69 | #include <linux/bio.h> | 69 | #include <linux/bio.h> |
70 | #include <linux/suspend.h> | 70 | #include <linux/freezer.h> |
71 | #include <linux/delay.h> | 71 | #include <linux/delay.h> |
72 | #include <linux/mutex.h> | 72 | #include <linux/mutex.h> |
73 | #include "jfs_incore.h" | 73 | #include "jfs_incore.h" |
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 0cccd1c39d75..b1a1c7296014 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c | |||
@@ -74,7 +74,7 @@ static inline void lock_metapage(struct metapage *mp) | |||
74 | } | 74 | } |
75 | 75 | ||
76 | #define METAPOOL_MIN_PAGES 32 | 76 | #define METAPOOL_MIN_PAGES 32 |
77 | static kmem_cache_t *metapage_cache; | 77 | static struct kmem_cache *metapage_cache; |
78 | static mempool_t *metapage_mempool; | 78 | static mempool_t *metapage_mempool; |
79 | 79 | ||
80 | #define MPS_PER_PAGE (PAGE_CACHE_SIZE >> L2PSIZE) | 80 | #define MPS_PER_PAGE (PAGE_CACHE_SIZE >> L2PSIZE) |
@@ -180,7 +180,7 @@ static inline void remove_metapage(struct page *page, struct metapage *mp) | |||
180 | 180 | ||
181 | #endif | 181 | #endif |
182 | 182 | ||
183 | static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) | 183 | static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) |
184 | { | 184 | { |
185 | struct metapage *mp = (struct metapage *)foo; | 185 | struct metapage *mp = (struct metapage *)foo; |
186 | 186 | ||
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c index 81f6f04af192..d558e51b0df8 100644 --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <linux/vmalloc.h> | 46 | #include <linux/vmalloc.h> |
47 | #include <linux/smp_lock.h> | 47 | #include <linux/smp_lock.h> |
48 | #include <linux/completion.h> | 48 | #include <linux/completion.h> |
49 | #include <linux/suspend.h> | 49 | #include <linux/freezer.h> |
50 | #include <linux/module.h> | 50 | #include <linux/module.h> |
51 | #include <linux/moduleparam.h> | 51 | #include <linux/moduleparam.h> |
52 | #include <linux/kthread.h> | 52 | #include <linux/kthread.h> |
diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 9c1c6e0e633d..846ac8f34513 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c | |||
@@ -44,7 +44,7 @@ MODULE_DESCRIPTION("The Journaled Filesystem (JFS)"); | |||
44 | MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); | 44 | MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM"); |
45 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
46 | 46 | ||
47 | static kmem_cache_t * jfs_inode_cachep; | 47 | static struct kmem_cache * jfs_inode_cachep; |
48 | 48 | ||
49 | static struct super_operations jfs_super_operations; | 49 | static struct super_operations jfs_super_operations; |
50 | static struct export_operations jfs_export_operations; | 50 | static struct export_operations jfs_export_operations; |
@@ -93,7 +93,7 @@ void jfs_error(struct super_block *sb, const char * function, ...) | |||
93 | va_list args; | 93 | va_list args; |
94 | 94 | ||
95 | va_start(args, function); | 95 | va_start(args, function); |
96 | vsprintf(error_buf, function, args); | 96 | vsnprintf(error_buf, sizeof(error_buf), function, args); |
97 | va_end(args); | 97 | va_end(args); |
98 | 98 | ||
99 | printk(KERN_ERR "ERROR: (device %s): %s\n", sb->s_id, error_buf); | 99 | printk(KERN_ERR "ERROR: (device %s): %s\n", sb->s_id, error_buf); |
@@ -748,7 +748,7 @@ static struct file_system_type jfs_fs_type = { | |||
748 | .fs_flags = FS_REQUIRES_DEV, | 748 | .fs_flags = FS_REQUIRES_DEV, |
749 | }; | 749 | }; |
750 | 750 | ||
751 | static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) | 751 | static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) |
752 | { | 752 | { |
753 | struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; | 753 | struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo; |
754 | 754 | ||
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 3d84f600b633..497c3cd59d52 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/nfs_fs.h> | 13 | #include <linux/nfs_fs.h> |
14 | #include <linux/utsname.h> | 14 | #include <linux/utsname.h> |
15 | #include <linux/smp_lock.h> | 15 | #include <linux/smp_lock.h> |
16 | #include <linux/freezer.h> | ||
16 | #include <linux/sunrpc/clnt.h> | 17 | #include <linux/sunrpc/clnt.h> |
17 | #include <linux/sunrpc/svc.h> | 18 | #include <linux/sunrpc/svc.h> |
18 | #include <linux/lockd/lockd.h> | 19 | #include <linux/lockd/lockd.h> |
@@ -729,7 +730,7 @@ static void nlmclnt_cancel_callback(struct rpc_task *task, void *data) | |||
729 | goto retry_cancel; | 730 | goto retry_cancel; |
730 | } | 731 | } |
731 | 732 | ||
732 | dprintk("lockd: cancel status %d (task %d)\n", | 733 | dprintk("lockd: cancel status %u (task %u)\n", |
733 | req->a_res.status, task->tk_pid); | 734 | req->a_res.status, task->tk_pid); |
734 | 735 | ||
735 | switch (req->a_res.status) { | 736 | switch (req->a_res.status) { |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index fb24a9730345..3d4610c2a266 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -36,34 +36,14 @@ static DEFINE_MUTEX(nlm_host_mutex); | |||
36 | static void nlm_gc_hosts(void); | 36 | static void nlm_gc_hosts(void); |
37 | static struct nsm_handle * __nsm_find(const struct sockaddr_in *, | 37 | static struct nsm_handle * __nsm_find(const struct sockaddr_in *, |
38 | const char *, int, int); | 38 | const char *, int, int); |
39 | 39 | static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, | |
40 | /* | 40 | const char *hostname, |
41 | * Find an NLM server handle in the cache. If there is none, create it. | 41 | int hostname_len); |
42 | */ | ||
43 | struct nlm_host * | ||
44 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, | ||
45 | const char *hostname, int hostname_len) | ||
46 | { | ||
47 | return nlm_lookup_host(0, sin, proto, version, | ||
48 | hostname, hostname_len); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Find an NLM client handle in the cache. If there is none, create it. | ||
53 | */ | ||
54 | struct nlm_host * | ||
55 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | ||
56 | const char *hostname, int hostname_len) | ||
57 | { | ||
58 | return nlm_lookup_host(1, &rqstp->rq_addr, | ||
59 | rqstp->rq_prot, rqstp->rq_vers, | ||
60 | hostname, hostname_len); | ||
61 | } | ||
62 | 42 | ||
63 | /* | 43 | /* |
64 | * Common host lookup routine for server & client | 44 | * Common host lookup routine for server & client |
65 | */ | 45 | */ |
66 | struct nlm_host * | 46 | static struct nlm_host * |
67 | nlm_lookup_host(int server, const struct sockaddr_in *sin, | 47 | nlm_lookup_host(int server, const struct sockaddr_in *sin, |
68 | int proto, int version, | 48 | int proto, int version, |
69 | const char *hostname, | 49 | const char *hostname, |
@@ -195,6 +175,29 @@ nlm_destroy_host(struct nlm_host *host) | |||
195 | } | 175 | } |
196 | 176 | ||
197 | /* | 177 | /* |
178 | * Find an NLM server handle in the cache. If there is none, create it. | ||
179 | */ | ||
180 | struct nlm_host * | ||
181 | nlmclnt_lookup_host(const struct sockaddr_in *sin, int proto, int version, | ||
182 | const char *hostname, int hostname_len) | ||
183 | { | ||
184 | return nlm_lookup_host(0, sin, proto, version, | ||
185 | hostname, hostname_len); | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Find an NLM client handle in the cache. If there is none, create it. | ||
190 | */ | ||
191 | struct nlm_host * | ||
192 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | ||
193 | const char *hostname, int hostname_len) | ||
194 | { | ||
195 | return nlm_lookup_host(1, &rqstp->rq_addr, | ||
196 | rqstp->rq_prot, rqstp->rq_vers, | ||
197 | hostname, hostname_len); | ||
198 | } | ||
199 | |||
200 | /* | ||
198 | * Create the NLM RPC client for an NLM peer | 201 | * Create the NLM RPC client for an NLM peer |
199 | */ | 202 | */ |
200 | struct rpc_clnt * | 203 | struct rpc_clnt * |
@@ -495,7 +498,7 @@ out: | |||
495 | return nsm; | 498 | return nsm; |
496 | } | 499 | } |
497 | 500 | ||
498 | struct nsm_handle * | 501 | static struct nsm_handle * |
499 | nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len) | 502 | nsm_find(const struct sockaddr_in *sin, const char *hostname, int hostname_len) |
500 | { | 503 | { |
501 | return __nsm_find(sin, hostname, hostname_len, 1); | 504 | return __nsm_find(sin, hostname, hostname_len, 1); |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 634139232aaf..8ca18085e68d 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -353,9 +353,6 @@ EXPORT_SYMBOL(lockd_down); | |||
353 | * Sysctl parameters (same as module parameters, different interface). | 353 | * Sysctl parameters (same as module parameters, different interface). |
354 | */ | 354 | */ |
355 | 355 | ||
356 | /* Something that isn't CTL_ANY, CTL_NONE or a value that may clash. */ | ||
357 | #define CTL_UNNUMBERED -2 | ||
358 | |||
359 | static ctl_table nlm_sysctls[] = { | 356 | static ctl_table nlm_sysctls[] = { |
360 | { | 357 | { |
361 | .ctl_name = CTL_UNNUMBERED, | 358 | .ctl_name = CTL_UNNUMBERED, |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 0ce5c81ff507..f67146a8199a 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
@@ -234,7 +234,7 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
234 | */ | 234 | */ |
235 | static void nlm4svc_callback_exit(struct rpc_task *task, void *data) | 235 | static void nlm4svc_callback_exit(struct rpc_task *task, void *data) |
236 | { | 236 | { |
237 | dprintk("lockd: %4d callback returned %d\n", task->tk_pid, | 237 | dprintk("lockd: %5u callback returned %d\n", task->tk_pid, |
238 | -task->tk_status); | 238 | -task->tk_status); |
239 | } | 239 | } |
240 | 240 | ||
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 32e99a6e8dca..3707c3a23e93 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -263,7 +263,7 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
263 | */ | 263 | */ |
264 | static void nlmsvc_callback_exit(struct rpc_task *task, void *data) | 264 | static void nlmsvc_callback_exit(struct rpc_task *task, void *data) |
265 | { | 265 | { |
266 | dprintk("lockd: %4d callback returned %d\n", task->tk_pid, | 266 | dprintk("lockd: %5u callback returned %d\n", task->tk_pid, |
267 | -task->tk_status); | 267 | -task->tk_status); |
268 | } | 268 | } |
269 | 269 | ||
diff --git a/fs/locks.c b/fs/locks.c index e0b6a80649a0..1cb0c57fedbd 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -142,12 +142,12 @@ int lease_break_time = 45; | |||
142 | static LIST_HEAD(file_lock_list); | 142 | static LIST_HEAD(file_lock_list); |
143 | static LIST_HEAD(blocked_list); | 143 | static LIST_HEAD(blocked_list); |
144 | 144 | ||
145 | static kmem_cache_t *filelock_cache __read_mostly; | 145 | static struct kmem_cache *filelock_cache __read_mostly; |
146 | 146 | ||
147 | /* Allocate an empty lock structure. */ | 147 | /* Allocate an empty lock structure. */ |
148 | static struct file_lock *locks_alloc_lock(void) | 148 | static struct file_lock *locks_alloc_lock(void) |
149 | { | 149 | { |
150 | return kmem_cache_alloc(filelock_cache, SLAB_KERNEL); | 150 | return kmem_cache_alloc(filelock_cache, GFP_KERNEL); |
151 | } | 151 | } |
152 | 152 | ||
153 | static void locks_release_private(struct file_lock *fl) | 153 | static void locks_release_private(struct file_lock *fl) |
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(locks_init_lock); | |||
199 | * Initialises the fields of the file lock which are invariant for | 199 | * Initialises the fields of the file lock which are invariant for |
200 | * free file_locks. | 200 | * free file_locks. |
201 | */ | 201 | */ |
202 | static void init_once(void *foo, kmem_cache_t *cache, unsigned long flags) | 202 | static void init_once(void *foo, struct kmem_cache *cache, unsigned long flags) |
203 | { | 203 | { |
204 | struct file_lock *lock = (struct file_lock *) foo; | 204 | struct file_lock *lock = (struct file_lock *) foo; |
205 | 205 | ||
diff --git a/fs/mbcache.c b/fs/mbcache.c index 0ff71256e65b..deeb9dc062d9 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c | |||
@@ -85,7 +85,7 @@ struct mb_cache { | |||
85 | #ifndef MB_CACHE_INDEXES_COUNT | 85 | #ifndef MB_CACHE_INDEXES_COUNT |
86 | int c_indexes_count; | 86 | int c_indexes_count; |
87 | #endif | 87 | #endif |
88 | kmem_cache_t *c_entry_cache; | 88 | struct kmem_cache *c_entry_cache; |
89 | struct list_head *c_block_hash; | 89 | struct list_head *c_block_hash; |
90 | struct list_head *c_indexes_hash[0]; | 90 | struct list_head *c_indexes_hash[0]; |
91 | }; | 91 | }; |
diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 1e36bae4d0eb..629e09b38c5c 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c | |||
@@ -51,12 +51,12 @@ static void minix_put_super(struct super_block *sb) | |||
51 | return; | 51 | return; |
52 | } | 52 | } |
53 | 53 | ||
54 | static kmem_cache_t * minix_inode_cachep; | 54 | static struct kmem_cache * minix_inode_cachep; |
55 | 55 | ||
56 | static struct inode *minix_alloc_inode(struct super_block *sb) | 56 | static struct inode *minix_alloc_inode(struct super_block *sb) |
57 | { | 57 | { |
58 | struct minix_inode_info *ei; | 58 | struct minix_inode_info *ei; |
59 | ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, SLAB_KERNEL); | 59 | ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL); |
60 | if (!ei) | 60 | if (!ei) |
61 | return NULL; | 61 | return NULL; |
62 | return &ei->vfs_inode; | 62 | return &ei->vfs_inode; |
@@ -67,7 +67,7 @@ static void minix_destroy_inode(struct inode *inode) | |||
67 | kmem_cache_free(minix_inode_cachep, minix_i(inode)); | 67 | kmem_cache_free(minix_inode_cachep, minix_i(inode)); |
68 | } | 68 | } |
69 | 69 | ||
70 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 70 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
71 | { | 71 | { |
72 | struct minix_inode_info *ei = (struct minix_inode_info *) foo; | 72 | struct minix_inode_info *ei = (struct minix_inode_info *) foo; |
73 | 73 | ||
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c index b0f01b3b0536..452461955cbd 100644 --- a/fs/msdos/namei.c +++ b/fs/msdos/namei.c | |||
@@ -654,6 +654,7 @@ static struct inode_operations msdos_dir_inode_operations = { | |||
654 | .rmdir = msdos_rmdir, | 654 | .rmdir = msdos_rmdir, |
655 | .rename = msdos_rename, | 655 | .rename = msdos_rename, |
656 | .setattr = fat_notify_change, | 656 | .setattr = fat_notify_change, |
657 | .getattr = fat_getattr, | ||
657 | }; | 658 | }; |
658 | 659 | ||
659 | static int msdos_fill_super(struct super_block *sb, void *data, int silent) | 660 | static int msdos_fill_super(struct super_block *sb, void *data, int silent) |
diff --git a/fs/namei.c b/fs/namei.c index 28d49b301d55..db1bca26d88c 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -249,9 +249,11 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
249 | 249 | ||
250 | /* | 250 | /* |
251 | * MAY_EXEC on regular files requires special handling: We override | 251 | * MAY_EXEC on regular files requires special handling: We override |
252 | * filesystem execute permissions if the mode bits aren't set. | 252 | * filesystem execute permissions if the mode bits aren't set or |
253 | * the fs is mounted with the "noexec" flag. | ||
253 | */ | 254 | */ |
254 | if ((mask & MAY_EXEC) && S_ISREG(mode) && !(mode & S_IXUGO)) | 255 | if ((mask & MAY_EXEC) && S_ISREG(mode) && (!(mode & S_IXUGO) || |
256 | (nd && nd->mnt && (nd->mnt->mnt_flags & MNT_NOEXEC)))) | ||
255 | return -EACCES; | 257 | return -EACCES; |
256 | 258 | ||
257 | /* Ordinary permission routines do not understand MAY_APPEND. */ | 259 | /* Ordinary permission routines do not understand MAY_APPEND. */ |
@@ -1996,8 +1998,7 @@ asmlinkage long sys_mkdir(const char __user *pathname, int mode) | |||
1996 | void dentry_unhash(struct dentry *dentry) | 1998 | void dentry_unhash(struct dentry *dentry) |
1997 | { | 1999 | { |
1998 | dget(dentry); | 2000 | dget(dentry); |
1999 | if (atomic_read(&dentry->d_count)) | 2001 | shrink_dcache_parent(dentry); |
2000 | shrink_dcache_parent(dentry); | ||
2001 | spin_lock(&dcache_lock); | 2002 | spin_lock(&dcache_lock); |
2002 | spin_lock(&dentry->d_lock); | 2003 | spin_lock(&dentry->d_lock); |
2003 | if (atomic_read(&dentry->d_count) == 2) | 2004 | if (atomic_read(&dentry->d_count) == 2) |
diff --git a/fs/namespace.c b/fs/namespace.c index 55442a6cf221..b00ac84ebbdd 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -36,7 +36,7 @@ static int event; | |||
36 | 36 | ||
37 | static struct list_head *mount_hashtable __read_mostly; | 37 | static struct list_head *mount_hashtable __read_mostly; |
38 | static int hash_mask __read_mostly, hash_bits __read_mostly; | 38 | static int hash_mask __read_mostly, hash_bits __read_mostly; |
39 | static kmem_cache_t *mnt_cache __read_mostly; | 39 | static struct kmem_cache *mnt_cache __read_mostly; |
40 | static struct rw_semaphore namespace_sem; | 40 | static struct rw_semaphore namespace_sem; |
41 | 41 | ||
42 | /* /sys/fs */ | 42 | /* /sys/fs */ |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 42e3bef270c9..fae53243bb92 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -40,12 +40,12 @@ static void ncp_delete_inode(struct inode *); | |||
40 | static void ncp_put_super(struct super_block *); | 40 | static void ncp_put_super(struct super_block *); |
41 | static int ncp_statfs(struct dentry *, struct kstatfs *); | 41 | static int ncp_statfs(struct dentry *, struct kstatfs *); |
42 | 42 | ||
43 | static kmem_cache_t * ncp_inode_cachep; | 43 | static struct kmem_cache * ncp_inode_cachep; |
44 | 44 | ||
45 | static struct inode *ncp_alloc_inode(struct super_block *sb) | 45 | static struct inode *ncp_alloc_inode(struct super_block *sb) |
46 | { | 46 | { |
47 | struct ncp_inode_info *ei; | 47 | struct ncp_inode_info *ei; |
48 | ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, SLAB_KERNEL); | 48 | ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL); |
49 | if (!ei) | 49 | if (!ei) |
50 | return NULL; | 50 | return NULL; |
51 | return &ei->vfs_inode; | 51 | return &ei->vfs_inode; |
@@ -56,7 +56,7 @@ static void ncp_destroy_inode(struct inode *inode) | |||
56 | kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); | 56 | kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode)); |
57 | } | 57 | } |
58 | 58 | ||
59 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 59 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
60 | { | 60 | { |
61 | struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; | 61 | struct ncp_inode_info *ei = (struct ncp_inode_info *) foo; |
62 | 62 | ||
@@ -577,12 +577,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
577 | server->rcv.ptr = (unsigned char*)&server->rcv.buf; | 577 | server->rcv.ptr = (unsigned char*)&server->rcv.buf; |
578 | server->rcv.len = 10; | 578 | server->rcv.len = 10; |
579 | server->rcv.state = 0; | 579 | server->rcv.state = 0; |
580 | INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc, server); | 580 | INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc); |
581 | INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc, server); | 581 | INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc); |
582 | sock->sk->sk_write_space = ncp_tcp_write_space; | 582 | sock->sk->sk_write_space = ncp_tcp_write_space; |
583 | } else { | 583 | } else { |
584 | INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc, server); | 584 | INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc); |
585 | INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc, server); | 585 | INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc); |
586 | server->timeout_tm.data = (unsigned long)server; | 586 | server->timeout_tm.data = (unsigned long)server; |
587 | server->timeout_tm.function = ncpdgram_timeout_call; | 587 | server->timeout_tm.function = ncpdgram_timeout_call; |
588 | } | 588 | } |
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 11c2b252ebed..e496d8b65e92 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c | |||
@@ -350,9 +350,10 @@ static void info_server(struct ncp_server *server, unsigned int id, const void * | |||
350 | } | 350 | } |
351 | } | 351 | } |
352 | 352 | ||
353 | void ncpdgram_rcv_proc(void *s) | 353 | void ncpdgram_rcv_proc(struct work_struct *work) |
354 | { | 354 | { |
355 | struct ncp_server *server = s; | 355 | struct ncp_server *server = |
356 | container_of(work, struct ncp_server, rcv.tq); | ||
356 | struct socket* sock; | 357 | struct socket* sock; |
357 | 358 | ||
358 | sock = server->ncp_sock; | 359 | sock = server->ncp_sock; |
@@ -468,9 +469,10 @@ static void __ncpdgram_timeout_proc(struct ncp_server *server) | |||
468 | } | 469 | } |
469 | } | 470 | } |
470 | 471 | ||
471 | void ncpdgram_timeout_proc(void *s) | 472 | void ncpdgram_timeout_proc(struct work_struct *work) |
472 | { | 473 | { |
473 | struct ncp_server *server = s; | 474 | struct ncp_server *server = |
475 | container_of(work, struct ncp_server, timeout_tq); | ||
474 | mutex_lock(&server->rcv.creq_mutex); | 476 | mutex_lock(&server->rcv.creq_mutex); |
475 | __ncpdgram_timeout_proc(server); | 477 | __ncpdgram_timeout_proc(server); |
476 | mutex_unlock(&server->rcv.creq_mutex); | 478 | mutex_unlock(&server->rcv.creq_mutex); |
@@ -652,18 +654,20 @@ skipdata:; | |||
652 | } | 654 | } |
653 | } | 655 | } |
654 | 656 | ||
655 | void ncp_tcp_rcv_proc(void *s) | 657 | void ncp_tcp_rcv_proc(struct work_struct *work) |
656 | { | 658 | { |
657 | struct ncp_server *server = s; | 659 | struct ncp_server *server = |
660 | container_of(work, struct ncp_server, rcv.tq); | ||
658 | 661 | ||
659 | mutex_lock(&server->rcv.creq_mutex); | 662 | mutex_lock(&server->rcv.creq_mutex); |
660 | __ncptcp_rcv_proc(server); | 663 | __ncptcp_rcv_proc(server); |
661 | mutex_unlock(&server->rcv.creq_mutex); | 664 | mutex_unlock(&server->rcv.creq_mutex); |
662 | } | 665 | } |
663 | 666 | ||
664 | void ncp_tcp_tx_proc(void *s) | 667 | void ncp_tcp_tx_proc(struct work_struct *work) |
665 | { | 668 | { |
666 | struct ncp_server *server = s; | 669 | struct ncp_server *server = |
670 | container_of(work, struct ncp_server, tx.tq); | ||
667 | 671 | ||
668 | mutex_lock(&server->rcv.creq_mutex); | 672 | mutex_lock(&server->rcv.creq_mutex); |
669 | __ncptcp_try_send(server); | 673 | __ncptcp_try_send(server); |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 5fea638743e4..23ab145daa2d 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -143,7 +143,7 @@ static struct nfs_client *nfs_alloc_client(const char *hostname, | |||
143 | INIT_LIST_HEAD(&clp->cl_state_owners); | 143 | INIT_LIST_HEAD(&clp->cl_state_owners); |
144 | INIT_LIST_HEAD(&clp->cl_unused); | 144 | INIT_LIST_HEAD(&clp->cl_unused); |
145 | spin_lock_init(&clp->cl_lock); | 145 | spin_lock_init(&clp->cl_lock); |
146 | INIT_WORK(&clp->cl_renewd, nfs4_renew_state, clp); | 146 | INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); |
147 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); | 147 | rpc_init_wait_queue(&clp->cl_rpcwaitq, "NFS client"); |
148 | clp->cl_boot_time = CURRENT_TIME; | 148 | clp->cl_boot_time = CURRENT_TIME; |
149 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; | 149 | clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED; |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index bdfabf854a51..f9d678f4ae06 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -58,7 +58,7 @@ | |||
58 | 58 | ||
59 | #define NFSDBG_FACILITY NFSDBG_VFS | 59 | #define NFSDBG_FACILITY NFSDBG_VFS |
60 | 60 | ||
61 | static kmem_cache_t *nfs_direct_cachep; | 61 | static struct kmem_cache *nfs_direct_cachep; |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * This represents a set of asynchronous requests that we're waiting on | 64 | * This represents a set of asynchronous requests that we're waiting on |
@@ -143,7 +143,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void) | |||
143 | { | 143 | { |
144 | struct nfs_direct_req *dreq; | 144 | struct nfs_direct_req *dreq; |
145 | 145 | ||
146 | dreq = kmem_cache_alloc(nfs_direct_cachep, SLAB_KERNEL); | 146 | dreq = kmem_cache_alloc(nfs_direct_cachep, GFP_KERNEL); |
147 | if (!dreq) | 147 | if (!dreq) |
148 | return NULL; | 148 | return NULL; |
149 | 149 | ||
@@ -307,9 +307,7 @@ static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned lo | |||
307 | 307 | ||
308 | data->task.tk_cookie = (unsigned long) inode; | 308 | data->task.tk_cookie = (unsigned long) inode; |
309 | 309 | ||
310 | lock_kernel(); | ||
311 | rpc_execute(&data->task); | 310 | rpc_execute(&data->task); |
312 | unlock_kernel(); | ||
313 | 311 | ||
314 | dfprintk(VFS, "NFS: %5u initiated direct read call (req %s/%Ld, %zu bytes @ offset %Lu)\n", | 312 | dfprintk(VFS, "NFS: %5u initiated direct read call (req %s/%Ld, %zu bytes @ offset %Lu)\n", |
315 | data->task.tk_pid, | 313 | data->task.tk_pid, |
@@ -475,9 +473,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | |||
475 | 473 | ||
476 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); | 474 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); |
477 | 475 | ||
478 | lock_kernel(); | ||
479 | rpc_execute(&data->task); | 476 | rpc_execute(&data->task); |
480 | unlock_kernel(); | ||
481 | } | 477 | } |
482 | 478 | ||
483 | static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) | 479 | static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode) |
@@ -641,9 +637,7 @@ static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned l | |||
641 | data->task.tk_priority = RPC_PRIORITY_NORMAL; | 637 | data->task.tk_priority = RPC_PRIORITY_NORMAL; |
642 | data->task.tk_cookie = (unsigned long) inode; | 638 | data->task.tk_cookie = (unsigned long) inode; |
643 | 639 | ||
644 | lock_kernel(); | ||
645 | rpc_execute(&data->task); | 640 | rpc_execute(&data->task); |
646 | unlock_kernel(); | ||
647 | 641 | ||
648 | dfprintk(VFS, "NFS: %5u initiated direct write call (req %s/%Ld, %zu bytes @ offset %Lu)\n", | 642 | dfprintk(VFS, "NFS: %5u initiated direct write call (req %s/%Ld, %zu bytes @ offset %Lu)\n", |
649 | data->task.tk_pid, | 643 | data->task.tk_pid, |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index cc93865cea93..8e28bffc35a0 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -307,28 +307,28 @@ static int nfs_commit_write(struct file *file, struct page *page, unsigned offse | |||
307 | 307 | ||
308 | static void nfs_invalidate_page(struct page *page, unsigned long offset) | 308 | static void nfs_invalidate_page(struct page *page, unsigned long offset) |
309 | { | 309 | { |
310 | struct inode *inode = page->mapping->host; | 310 | if (offset != 0) |
311 | 311 | return; | |
312 | /* Cancel any unstarted writes on this page */ | 312 | /* Cancel any unstarted writes on this page */ |
313 | if (offset == 0) | 313 | nfs_wb_page_priority(page->mapping->host, page, FLUSH_INVALIDATE); |
314 | nfs_sync_inode_wait(inode, page->index, 1, FLUSH_INVALIDATE); | ||
315 | } | 314 | } |
316 | 315 | ||
317 | static int nfs_release_page(struct page *page, gfp_t gfp) | 316 | static int nfs_release_page(struct page *page, gfp_t gfp) |
318 | { | 317 | { |
319 | if (gfp & __GFP_FS) | 318 | /* |
320 | return !nfs_wb_page(page->mapping->host, page); | 319 | * Avoid deadlock on nfs_wait_on_request(). |
321 | else | 320 | */ |
322 | /* | 321 | if (!(gfp & __GFP_FS)) |
323 | * Avoid deadlock on nfs_wait_on_request(). | ||
324 | */ | ||
325 | return 0; | 322 | return 0; |
323 | /* Hack... Force nfs_wb_page() to write out the page */ | ||
324 | SetPageDirty(page); | ||
325 | return !nfs_wb_page(page->mapping->host, page); | ||
326 | } | 326 | } |
327 | 327 | ||
328 | const struct address_space_operations nfs_file_aops = { | 328 | const struct address_space_operations nfs_file_aops = { |
329 | .readpage = nfs_readpage, | 329 | .readpage = nfs_readpage, |
330 | .readpages = nfs_readpages, | 330 | .readpages = nfs_readpages, |
331 | .set_page_dirty = __set_page_dirty_nobuffers, | 331 | .set_page_dirty = nfs_set_page_dirty, |
332 | .writepage = nfs_writepage, | 332 | .writepage = nfs_writepage, |
333 | .writepages = nfs_writepages, | 333 | .writepages = nfs_writepages, |
334 | .prepare_write = nfs_prepare_write, | 334 | .prepare_write = nfs_prepare_write, |
@@ -375,6 +375,12 @@ static ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov, | |||
375 | 375 | ||
376 | nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); | 376 | nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count); |
377 | result = generic_file_aio_write(iocb, iov, nr_segs, pos); | 377 | result = generic_file_aio_write(iocb, iov, nr_segs, pos); |
378 | /* Return error values for O_SYNC and IS_SYNC() */ | ||
379 | if (result >= 0 && (IS_SYNC(inode) || (iocb->ki_filp->f_flags & O_SYNC))) { | ||
380 | int err = nfs_fsync(iocb->ki_filp, dentry, 1); | ||
381 | if (err < 0) | ||
382 | result = err; | ||
383 | } | ||
378 | out: | 384 | out: |
379 | return result; | 385 | return result; |
380 | 386 | ||
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 08cc4c5919ab..36680d1061b0 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -55,7 +55,7 @@ static int nfs_update_inode(struct inode *, struct nfs_fattr *); | |||
55 | 55 | ||
56 | static void nfs_zap_acl_cache(struct inode *); | 56 | static void nfs_zap_acl_cache(struct inode *); |
57 | 57 | ||
58 | static kmem_cache_t * nfs_inode_cachep; | 58 | static struct kmem_cache * nfs_inode_cachep; |
59 | 59 | ||
60 | static inline unsigned long | 60 | static inline unsigned long |
61 | nfs_fattr_to_ino_t(struct nfs_fattr *fattr) | 61 | nfs_fattr_to_ino_t(struct nfs_fattr *fattr) |
@@ -422,7 +422,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
422 | int err; | 422 | int err; |
423 | 423 | ||
424 | /* Flush out writes to the server in order to update c/mtime */ | 424 | /* Flush out writes to the server in order to update c/mtime */ |
425 | nfs_sync_inode_wait(inode, 0, 0, FLUSH_NOCOMMIT); | 425 | nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); |
426 | 426 | ||
427 | /* | 427 | /* |
428 | * We may force a getattr if the user cares about atime. | 428 | * We may force a getattr if the user cares about atime. |
@@ -1080,7 +1080,7 @@ void nfs4_clear_inode(struct inode *inode) | |||
1080 | struct inode *nfs_alloc_inode(struct super_block *sb) | 1080 | struct inode *nfs_alloc_inode(struct super_block *sb) |
1081 | { | 1081 | { |
1082 | struct nfs_inode *nfsi; | 1082 | struct nfs_inode *nfsi; |
1083 | nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL); | 1083 | nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, GFP_KERNEL); |
1084 | if (!nfsi) | 1084 | if (!nfsi) |
1085 | return NULL; | 1085 | return NULL; |
1086 | nfsi->flags = 0UL; | 1086 | nfsi->flags = 0UL; |
@@ -1111,7 +1111,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) | |||
1111 | #endif | 1111 | #endif |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 1114 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
1115 | { | 1115 | { |
1116 | struct nfs_inode *nfsi = (struct nfs_inode *) foo; | 1116 | struct nfs_inode *nfsi = (struct nfs_inode *) foo; |
1117 | 1117 | ||
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index d205466233f6..a28f6ce2e131 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -217,3 +217,21 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize) | |||
217 | if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) | 217 | if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0) |
218 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 218 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
219 | } | 219 | } |
220 | |||
221 | /* | ||
222 | * Determine the number of bytes of data the page contains | ||
223 | */ | ||
224 | static inline | ||
225 | unsigned int nfs_page_length(struct page *page) | ||
226 | { | ||
227 | loff_t i_size = i_size_read(page->mapping->host); | ||
228 | |||
229 | if (i_size > 0) { | ||
230 | pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT; | ||
231 | if (page->index < end_index) | ||
232 | return PAGE_CACHE_SIZE; | ||
233 | if (page->index == end_index) | ||
234 | return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1; | ||
235 | } | ||
236 | return 0; | ||
237 | } | ||
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c index ec1114b33d89..371b804e7cc8 100644 --- a/fs/nfs/namespace.c +++ b/fs/nfs/namespace.c | |||
@@ -18,10 +18,10 @@ | |||
18 | 18 | ||
19 | #define NFSDBG_FACILITY NFSDBG_VFS | 19 | #define NFSDBG_FACILITY NFSDBG_VFS |
20 | 20 | ||
21 | static void nfs_expire_automounts(void *list); | 21 | static void nfs_expire_automounts(struct work_struct *work); |
22 | 22 | ||
23 | LIST_HEAD(nfs_automount_list); | 23 | LIST_HEAD(nfs_automount_list); |
24 | static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list); | 24 | static DECLARE_DELAYED_WORK(nfs_automount_task, nfs_expire_automounts); |
25 | int nfs_mountpoint_expiry_timeout = 500 * HZ; | 25 | int nfs_mountpoint_expiry_timeout = 500 * HZ; |
26 | 26 | ||
27 | static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, | 27 | static struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent, |
@@ -164,9 +164,9 @@ struct inode_operations nfs_referral_inode_operations = { | |||
164 | .follow_link = nfs_follow_mountpoint, | 164 | .follow_link = nfs_follow_mountpoint, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static void nfs_expire_automounts(void *data) | 167 | static void nfs_expire_automounts(struct work_struct *work) |
168 | { | 168 | { |
169 | struct list_head *list = (struct list_head *)data; | 169 | struct list_head *list = &nfs_automount_list; |
170 | 170 | ||
171 | mark_mounts_for_expiry(list); | 171 | mark_mounts_for_expiry(list); |
172 | if (!list_empty(list)) | 172 | if (!list_empty(list)) |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index e5f128ffc32d..510ae524f3fd 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -276,51 +276,6 @@ static int nfs3_proc_read(struct nfs_read_data *rdata) | |||
276 | return status; | 276 | return status; |
277 | } | 277 | } |
278 | 278 | ||
279 | static int nfs3_proc_write(struct nfs_write_data *wdata) | ||
280 | { | ||
281 | int rpcflags = wdata->flags; | ||
282 | struct inode * inode = wdata->inode; | ||
283 | struct nfs_fattr * fattr = wdata->res.fattr; | ||
284 | struct rpc_message msg = { | ||
285 | .rpc_proc = &nfs3_procedures[NFS3PROC_WRITE], | ||
286 | .rpc_argp = &wdata->args, | ||
287 | .rpc_resp = &wdata->res, | ||
288 | .rpc_cred = wdata->cred, | ||
289 | }; | ||
290 | int status; | ||
291 | |||
292 | dprintk("NFS call write %d @ %Ld\n", wdata->args.count, | ||
293 | (long long) wdata->args.offset); | ||
294 | nfs_fattr_init(fattr); | ||
295 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags); | ||
296 | if (status >= 0) | ||
297 | nfs_post_op_update_inode(inode, fattr); | ||
298 | dprintk("NFS reply write: %d\n", status); | ||
299 | return status < 0? status : wdata->res.count; | ||
300 | } | ||
301 | |||
302 | static int nfs3_proc_commit(struct nfs_write_data *cdata) | ||
303 | { | ||
304 | struct inode * inode = cdata->inode; | ||
305 | struct nfs_fattr * fattr = cdata->res.fattr; | ||
306 | struct rpc_message msg = { | ||
307 | .rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT], | ||
308 | .rpc_argp = &cdata->args, | ||
309 | .rpc_resp = &cdata->res, | ||
310 | .rpc_cred = cdata->cred, | ||
311 | }; | ||
312 | int status; | ||
313 | |||
314 | dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, | ||
315 | (long long) cdata->args.offset); | ||
316 | nfs_fattr_init(fattr); | ||
317 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | ||
318 | if (status >= 0) | ||
319 | nfs_post_op_update_inode(inode, fattr); | ||
320 | dprintk("NFS reply commit: %d\n", status); | ||
321 | return status; | ||
322 | } | ||
323 | |||
324 | /* | 279 | /* |
325 | * Create a regular file. | 280 | * Create a regular file. |
326 | * For now, we don't implement O_EXCL. | 281 | * For now, we don't implement O_EXCL. |
@@ -369,7 +324,7 @@ again: | |||
369 | 324 | ||
370 | /* If the server doesn't support the exclusive creation semantics, | 325 | /* If the server doesn't support the exclusive creation semantics, |
371 | * try again with simple 'guarded' mode. */ | 326 | * try again with simple 'guarded' mode. */ |
372 | if (status == NFSERR_NOTSUPP) { | 327 | if (status == -ENOTSUPP) { |
373 | switch (arg.createmode) { | 328 | switch (arg.createmode) { |
374 | case NFS3_CREATE_EXCLUSIVE: | 329 | case NFS3_CREATE_EXCLUSIVE: |
375 | arg.createmode = NFS3_CREATE_GUARDED; | 330 | arg.createmode = NFS3_CREATE_GUARDED; |
@@ -690,8 +645,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
690 | }; | 645 | }; |
691 | int status; | 646 | int status; |
692 | 647 | ||
693 | lock_kernel(); | ||
694 | |||
695 | if (plus) | 648 | if (plus) |
696 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; | 649 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; |
697 | 650 | ||
@@ -702,7 +655,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
702 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 655 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
703 | nfs_refresh_inode(dir, &dir_attr); | 656 | nfs_refresh_inode(dir, &dir_attr); |
704 | dprintk("NFS reply readdir: %d\n", status); | 657 | dprintk("NFS reply readdir: %d\n", status); |
705 | unlock_kernel(); | ||
706 | return status; | 658 | return status; |
707 | } | 659 | } |
708 | 660 | ||
@@ -904,8 +856,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = { | |||
904 | .access = nfs3_proc_access, | 856 | .access = nfs3_proc_access, |
905 | .readlink = nfs3_proc_readlink, | 857 | .readlink = nfs3_proc_readlink, |
906 | .read = nfs3_proc_read, | 858 | .read = nfs3_proc_read, |
907 | .write = nfs3_proc_write, | ||
908 | .commit = nfs3_proc_commit, | ||
909 | .create = nfs3_proc_create, | 859 | .create = nfs3_proc_create, |
910 | .remove = nfs3_proc_remove, | 860 | .remove = nfs3_proc_remove, |
911 | .unlink_setup = nfs3_proc_unlink_setup, | 861 | .unlink_setup = nfs3_proc_unlink_setup, |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 6f346677332d..c26cd978c7cc 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
@@ -185,7 +185,7 @@ extern const u32 nfs4_fs_locations_bitmap[2]; | |||
185 | extern void nfs4_schedule_state_renewal(struct nfs_client *); | 185 | extern void nfs4_schedule_state_renewal(struct nfs_client *); |
186 | extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); | 186 | extern void nfs4_renewd_prepare_shutdown(struct nfs_server *); |
187 | extern void nfs4_kill_renewd(struct nfs_client *); | 187 | extern void nfs4_kill_renewd(struct nfs_client *); |
188 | extern void nfs4_renew_state(void *); | 188 | extern void nfs4_renew_state(struct work_struct *); |
189 | 189 | ||
190 | /* nfs4state.c */ | 190 | /* nfs4state.c */ |
191 | struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); | 191 | struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8118036cc449..ee458aeab24a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -636,7 +636,7 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data) | |||
636 | smp_wmb(); | 636 | smp_wmb(); |
637 | } else | 637 | } else |
638 | status = data->rpc_status; | 638 | status = data->rpc_status; |
639 | rpc_release_task(task); | 639 | rpc_put_task(task); |
640 | return status; | 640 | return status; |
641 | } | 641 | } |
642 | 642 | ||
@@ -742,7 +742,7 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
742 | smp_wmb(); | 742 | smp_wmb(); |
743 | } else | 743 | } else |
744 | status = data->rpc_status; | 744 | status = data->rpc_status; |
745 | rpc_release_task(task); | 745 | rpc_put_task(task); |
746 | if (status != 0) | 746 | if (status != 0) |
747 | return status; | 747 | return status; |
748 | 748 | ||
@@ -1775,89 +1775,6 @@ static int nfs4_proc_read(struct nfs_read_data *rdata) | |||
1775 | return err; | 1775 | return err; |
1776 | } | 1776 | } |
1777 | 1777 | ||
1778 | static int _nfs4_proc_write(struct nfs_write_data *wdata) | ||
1779 | { | ||
1780 | int rpcflags = wdata->flags; | ||
1781 | struct inode *inode = wdata->inode; | ||
1782 | struct nfs_fattr *fattr = wdata->res.fattr; | ||
1783 | struct nfs_server *server = NFS_SERVER(inode); | ||
1784 | struct rpc_message msg = { | ||
1785 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE], | ||
1786 | .rpc_argp = &wdata->args, | ||
1787 | .rpc_resp = &wdata->res, | ||
1788 | .rpc_cred = wdata->cred, | ||
1789 | }; | ||
1790 | int status; | ||
1791 | |||
1792 | dprintk("NFS call write %d @ %Ld\n", wdata->args.count, | ||
1793 | (long long) wdata->args.offset); | ||
1794 | |||
1795 | wdata->args.bitmask = server->attr_bitmask; | ||
1796 | wdata->res.server = server; | ||
1797 | wdata->timestamp = jiffies; | ||
1798 | nfs_fattr_init(fattr); | ||
1799 | status = rpc_call_sync(server->client, &msg, rpcflags); | ||
1800 | dprintk("NFS reply write: %d\n", status); | ||
1801 | if (status < 0) | ||
1802 | return status; | ||
1803 | renew_lease(server, wdata->timestamp); | ||
1804 | nfs_post_op_update_inode(inode, fattr); | ||
1805 | return wdata->res.count; | ||
1806 | } | ||
1807 | |||
1808 | static int nfs4_proc_write(struct nfs_write_data *wdata) | ||
1809 | { | ||
1810 | struct nfs4_exception exception = { }; | ||
1811 | int err; | ||
1812 | do { | ||
1813 | err = nfs4_handle_exception(NFS_SERVER(wdata->inode), | ||
1814 | _nfs4_proc_write(wdata), | ||
1815 | &exception); | ||
1816 | } while (exception.retry); | ||
1817 | return err; | ||
1818 | } | ||
1819 | |||
1820 | static int _nfs4_proc_commit(struct nfs_write_data *cdata) | ||
1821 | { | ||
1822 | struct inode *inode = cdata->inode; | ||
1823 | struct nfs_fattr *fattr = cdata->res.fattr; | ||
1824 | struct nfs_server *server = NFS_SERVER(inode); | ||
1825 | struct rpc_message msg = { | ||
1826 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT], | ||
1827 | .rpc_argp = &cdata->args, | ||
1828 | .rpc_resp = &cdata->res, | ||
1829 | .rpc_cred = cdata->cred, | ||
1830 | }; | ||
1831 | int status; | ||
1832 | |||
1833 | dprintk("NFS call commit %d @ %Ld\n", cdata->args.count, | ||
1834 | (long long) cdata->args.offset); | ||
1835 | |||
1836 | cdata->args.bitmask = server->attr_bitmask; | ||
1837 | cdata->res.server = server; | ||
1838 | cdata->timestamp = jiffies; | ||
1839 | nfs_fattr_init(fattr); | ||
1840 | status = rpc_call_sync(server->client, &msg, 0); | ||
1841 | if (status >= 0) | ||
1842 | renew_lease(server, cdata->timestamp); | ||
1843 | dprintk("NFS reply commit: %d\n", status); | ||
1844 | if (status >= 0) | ||
1845 | nfs_post_op_update_inode(inode, fattr); | ||
1846 | return status; | ||
1847 | } | ||
1848 | |||
1849 | static int nfs4_proc_commit(struct nfs_write_data *cdata) | ||
1850 | { | ||
1851 | struct nfs4_exception exception = { }; | ||
1852 | int err; | ||
1853 | do { | ||
1854 | err = nfs4_handle_exception(NFS_SERVER(cdata->inode), | ||
1855 | _nfs4_proc_commit(cdata), | ||
1856 | &exception); | ||
1857 | } while (exception.retry); | ||
1858 | return err; | ||
1859 | } | ||
1860 | |||
1861 | /* | 1778 | /* |
1862 | * Got race? | 1779 | * Got race? |
1863 | * We will need to arrange for the VFS layer to provide an atomic open. | 1780 | * We will need to arrange for the VFS layer to provide an atomic open. |
@@ -2223,13 +2140,11 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
2223 | dentry->d_parent->d_name.name, | 2140 | dentry->d_parent->d_name.name, |
2224 | dentry->d_name.name, | 2141 | dentry->d_name.name, |
2225 | (unsigned long long)cookie); | 2142 | (unsigned long long)cookie); |
2226 | lock_kernel(); | ||
2227 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); | 2143 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); |
2228 | res.pgbase = args.pgbase; | 2144 | res.pgbase = args.pgbase; |
2229 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 2145 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
2230 | if (status == 0) | 2146 | if (status == 0) |
2231 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); | 2147 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); |
2232 | unlock_kernel(); | ||
2233 | dprintk("%s: returns %d\n", __FUNCTION__, status); | 2148 | dprintk("%s: returns %d\n", __FUNCTION__, status); |
2234 | return status; | 2149 | return status; |
2235 | } | 2150 | } |
@@ -3067,7 +2982,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co | |||
3067 | if (status == 0) | 2982 | if (status == 0) |
3068 | nfs_post_op_update_inode(inode, &data->fattr); | 2983 | nfs_post_op_update_inode(inode, &data->fattr); |
3069 | } | 2984 | } |
3070 | rpc_release_task(task); | 2985 | rpc_put_task(task); |
3071 | return status; | 2986 | return status; |
3072 | } | 2987 | } |
3073 | 2988 | ||
@@ -3314,7 +3229,7 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock * | |||
3314 | if (IS_ERR(task)) | 3229 | if (IS_ERR(task)) |
3315 | goto out; | 3230 | goto out; |
3316 | status = nfs4_wait_for_completion_rpc_task(task); | 3231 | status = nfs4_wait_for_completion_rpc_task(task); |
3317 | rpc_release_task(task); | 3232 | rpc_put_task(task); |
3318 | out: | 3233 | out: |
3319 | return status; | 3234 | return status; |
3320 | } | 3235 | } |
@@ -3430,7 +3345,7 @@ static void nfs4_lock_release(void *calldata) | |||
3430 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, | 3345 | task = nfs4_do_unlck(&data->fl, data->ctx, data->lsp, |
3431 | data->arg.lock_seqid); | 3346 | data->arg.lock_seqid); |
3432 | if (!IS_ERR(task)) | 3347 | if (!IS_ERR(task)) |
3433 | rpc_release_task(task); | 3348 | rpc_put_task(task); |
3434 | dprintk("%s: cancelling lock!\n", __FUNCTION__); | 3349 | dprintk("%s: cancelling lock!\n", __FUNCTION__); |
3435 | } else | 3350 | } else |
3436 | nfs_free_seqid(data->arg.lock_seqid); | 3351 | nfs_free_seqid(data->arg.lock_seqid); |
@@ -3472,7 +3387,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f | |||
3472 | ret = -EAGAIN; | 3387 | ret = -EAGAIN; |
3473 | } else | 3388 | } else |
3474 | data->cancelled = 1; | 3389 | data->cancelled = 1; |
3475 | rpc_release_task(task); | 3390 | rpc_put_task(task); |
3476 | dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret); | 3391 | dprintk("%s: done, ret = %d!\n", __FUNCTION__, ret); |
3477 | return ret; | 3392 | return ret; |
3478 | } | 3393 | } |
@@ -3732,8 +3647,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = { | |||
3732 | .access = nfs4_proc_access, | 3647 | .access = nfs4_proc_access, |
3733 | .readlink = nfs4_proc_readlink, | 3648 | .readlink = nfs4_proc_readlink, |
3734 | .read = nfs4_proc_read, | 3649 | .read = nfs4_proc_read, |
3735 | .write = nfs4_proc_write, | ||
3736 | .commit = nfs4_proc_commit, | ||
3737 | .create = nfs4_proc_create, | 3650 | .create = nfs4_proc_create, |
3738 | .remove = nfs4_proc_remove, | 3651 | .remove = nfs4_proc_remove, |
3739 | .unlink_setup = nfs4_proc_unlink_setup, | 3652 | .unlink_setup = nfs4_proc_unlink_setup, |
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c index 7b6df1852e75..823298561c0a 100644 --- a/fs/nfs/nfs4renewd.c +++ b/fs/nfs/nfs4renewd.c | |||
@@ -59,9 +59,10 @@ | |||
59 | #define NFSDBG_FACILITY NFSDBG_PROC | 59 | #define NFSDBG_FACILITY NFSDBG_PROC |
60 | 60 | ||
61 | void | 61 | void |
62 | nfs4_renew_state(void *data) | 62 | nfs4_renew_state(struct work_struct *work) |
63 | { | 63 | { |
64 | struct nfs_client *clp = (struct nfs_client *)data; | 64 | struct nfs_client *clp = |
65 | container_of(work, struct nfs_client, cl_renewd.work); | ||
65 | struct rpc_cred *cred; | 66 | struct rpc_cred *cred; |
66 | long lease, timeout; | 67 | long lease, timeout; |
67 | unsigned long last, now; | 68 | unsigned long last, now; |
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 8dfefe41a8da..75f819dc0255 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
@@ -98,7 +98,7 @@ | |||
98 | static char nfs_root_name[256] __initdata = ""; | 98 | static char nfs_root_name[256] __initdata = ""; |
99 | 99 | ||
100 | /* Address of NFS server */ | 100 | /* Address of NFS server */ |
101 | static __u32 servaddr __initdata = 0; | 101 | static __be32 servaddr __initdata = 0; |
102 | 102 | ||
103 | /* Name of directory to mount */ | 103 | /* Name of directory to mount */ |
104 | static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, }; | 104 | static char nfs_path[NFS_MAXPATHLEN] __initdata = { 0, }; |
@@ -327,7 +327,7 @@ static int __init root_nfs_name(char *name) | |||
327 | */ | 327 | */ |
328 | static int __init root_nfs_addr(void) | 328 | static int __init root_nfs_addr(void) |
329 | { | 329 | { |
330 | if ((servaddr = root_server_addr) == INADDR_NONE) { | 330 | if ((servaddr = root_server_addr) == htonl(INADDR_NONE)) { |
331 | printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n"); | 331 | printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n"); |
332 | return -1; | 332 | return -1; |
333 | } | 333 | } |
@@ -411,7 +411,7 @@ __setup("nfsroot=", nfs_root_setup); | |||
411 | * Construct sockaddr_in from address and port number. | 411 | * Construct sockaddr_in from address and port number. |
412 | */ | 412 | */ |
413 | static inline void | 413 | static inline void |
414 | set_sockaddr(struct sockaddr_in *sin, __u32 addr, __u16 port) | 414 | set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port) |
415 | { | 415 | { |
416 | sin->sin_family = AF_INET; | 416 | sin->sin_family = AF_INET; |
417 | sin->sin_addr.s_addr = addr; | 417 | sin->sin_addr.s_addr = addr; |
@@ -468,14 +468,13 @@ static int __init root_nfs_ports(void) | |||
468 | dprintk("Root-NFS: Portmapper on server returned %d " | 468 | dprintk("Root-NFS: Portmapper on server returned %d " |
469 | "as nfsd port\n", port); | 469 | "as nfsd port\n", port); |
470 | } | 470 | } |
471 | nfs_port = htons(nfs_port); | ||
472 | 471 | ||
473 | if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { | 472 | if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { |
474 | printk(KERN_ERR "Root-NFS: Unable to get mountd port " | 473 | printk(KERN_ERR "Root-NFS: Unable to get mountd port " |
475 | "number from server, using default\n"); | 474 | "number from server, using default\n"); |
476 | port = mountd_port; | 475 | port = mountd_port; |
477 | } | 476 | } |
478 | mount_port = htons(port); | 477 | mount_port = port; |
479 | dprintk("Root-NFS: mountd port is %d\n", port); | 478 | dprintk("Root-NFS: mountd port is %d\n", port); |
480 | 479 | ||
481 | return 0; | 480 | return 0; |
@@ -496,7 +495,7 @@ static int __init root_nfs_get_handle(void) | |||
496 | int version = (nfs_data.flags & NFS_MOUNT_VER3) ? | 495 | int version = (nfs_data.flags & NFS_MOUNT_VER3) ? |
497 | NFS_MNT3_VERSION : NFS_MNT_VERSION; | 496 | NFS_MNT3_VERSION : NFS_MNT_VERSION; |
498 | 497 | ||
499 | set_sockaddr(&sin, servaddr, mount_port); | 498 | set_sockaddr(&sin, servaddr, htons(mount_port)); |
500 | status = nfsroot_mount(&sin, nfs_path, &fh, version, protocol); | 499 | status = nfsroot_mount(&sin, nfs_path, &fh, version, protocol); |
501 | if (status < 0) | 500 | if (status < 0) |
502 | printk(KERN_ERR "Root-NFS: Server returned error %d " | 501 | printk(KERN_ERR "Root-NFS: Server returned error %d " |
@@ -519,6 +518,6 @@ void * __init nfs_root_data(void) | |||
519 | || root_nfs_ports() < 0 | 518 | || root_nfs_ports() < 0 |
520 | || root_nfs_get_handle() < 0) | 519 | || root_nfs_get_handle() < 0) |
521 | return NULL; | 520 | return NULL; |
522 | set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port); | 521 | set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, htons(nfs_port)); |
523 | return (void*)&nfs_data; | 522 | return (void*)&nfs_data; |
524 | } | 523 | } |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 829af323f288..ca4b1d4ff42b 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -17,16 +17,17 @@ | |||
17 | #include <linux/nfs_page.h> | 17 | #include <linux/nfs_page.h> |
18 | #include <linux/nfs_fs.h> | 18 | #include <linux/nfs_fs.h> |
19 | #include <linux/nfs_mount.h> | 19 | #include <linux/nfs_mount.h> |
20 | #include <linux/writeback.h> | ||
20 | 21 | ||
21 | #define NFS_PARANOIA 1 | 22 | #define NFS_PARANOIA 1 |
22 | 23 | ||
23 | static kmem_cache_t *nfs_page_cachep; | 24 | static struct kmem_cache *nfs_page_cachep; |
24 | 25 | ||
25 | static inline struct nfs_page * | 26 | static inline struct nfs_page * |
26 | nfs_page_alloc(void) | 27 | nfs_page_alloc(void) |
27 | { | 28 | { |
28 | struct nfs_page *p; | 29 | struct nfs_page *p; |
29 | p = kmem_cache_alloc(nfs_page_cachep, SLAB_KERNEL); | 30 | p = kmem_cache_alloc(nfs_page_cachep, GFP_KERNEL); |
30 | if (p) { | 31 | if (p) { |
31 | memset(p, 0, sizeof(*p)); | 32 | memset(p, 0, sizeof(*p)); |
32 | INIT_LIST_HEAD(&p->wb_list); | 33 | INIT_LIST_HEAD(&p->wb_list); |
@@ -268,11 +269,10 @@ nfs_coalesce_requests(struct list_head *head, struct list_head *dst, | |||
268 | 269 | ||
269 | #define NFS_SCAN_MAXENTRIES 16 | 270 | #define NFS_SCAN_MAXENTRIES 16 |
270 | /** | 271 | /** |
271 | * nfs_scan_lock_dirty - Scan the radix tree for dirty requests | 272 | * nfs_scan_dirty - Scan the radix tree for dirty requests |
272 | * @nfsi: NFS inode | 273 | * @mapping: pointer to address space |
274 | * @wbc: writeback_control structure | ||
273 | * @dst: Destination list | 275 | * @dst: Destination list |
274 | * @idx_start: lower bound of page->index to scan | ||
275 | * @npages: idx_start + npages sets the upper bound to scan. | ||
276 | * | 276 | * |
277 | * Moves elements from one of the inode request lists. | 277 | * Moves elements from one of the inode request lists. |
278 | * If the number of requests is set to 0, the entire address_space | 278 | * If the number of requests is set to 0, the entire address_space |
@@ -280,46 +280,63 @@ nfs_coalesce_requests(struct list_head *head, struct list_head *dst, | |||
280 | * The requests are *not* checked to ensure that they form a contiguous set. | 280 | * The requests are *not* checked to ensure that they form a contiguous set. |
281 | * You must be holding the inode's req_lock when calling this function | 281 | * You must be holding the inode's req_lock when calling this function |
282 | */ | 282 | */ |
283 | int | 283 | long nfs_scan_dirty(struct address_space *mapping, |
284 | nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst, | 284 | struct writeback_control *wbc, |
285 | unsigned long idx_start, unsigned int npages) | 285 | struct list_head *dst) |
286 | { | 286 | { |
287 | struct nfs_inode *nfsi = NFS_I(mapping->host); | ||
287 | struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES]; | 288 | struct nfs_page *pgvec[NFS_SCAN_MAXENTRIES]; |
288 | struct nfs_page *req; | 289 | struct nfs_page *req; |
289 | unsigned long idx_end; | 290 | pgoff_t idx_start, idx_end; |
291 | long res = 0; | ||
290 | int found, i; | 292 | int found, i; |
291 | int res; | ||
292 | 293 | ||
293 | res = 0; | 294 | if (nfsi->ndirty == 0) |
294 | if (npages == 0) | 295 | return 0; |
295 | idx_end = ~0; | 296 | if (wbc->range_cyclic) { |
296 | else | 297 | idx_start = 0; |
297 | idx_end = idx_start + npages - 1; | 298 | idx_end = ULONG_MAX; |
299 | } else if (wbc->range_end == 0) { | ||
300 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | ||
301 | idx_end = ULONG_MAX; | ||
302 | } else { | ||
303 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | ||
304 | idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; | ||
305 | } | ||
298 | 306 | ||
299 | for (;;) { | 307 | for (;;) { |
308 | unsigned int toscan = NFS_SCAN_MAXENTRIES; | ||
309 | |||
300 | found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, | 310 | found = radix_tree_gang_lookup_tag(&nfsi->nfs_page_tree, |
301 | (void **)&pgvec[0], idx_start, NFS_SCAN_MAXENTRIES, | 311 | (void **)&pgvec[0], idx_start, toscan, |
302 | NFS_PAGE_TAG_DIRTY); | 312 | NFS_PAGE_TAG_DIRTY); |
313 | |||
314 | /* Did we make progress? */ | ||
303 | if (found <= 0) | 315 | if (found <= 0) |
304 | break; | 316 | break; |
317 | |||
305 | for (i = 0; i < found; i++) { | 318 | for (i = 0; i < found; i++) { |
306 | req = pgvec[i]; | 319 | req = pgvec[i]; |
307 | if (req->wb_index > idx_end) | 320 | if (!wbc->range_cyclic && req->wb_index > idx_end) |
308 | goto out; | 321 | goto out; |
309 | 322 | ||
323 | /* Try to lock request and mark it for writeback */ | ||
324 | if (!nfs_set_page_writeback_locked(req)) | ||
325 | goto next; | ||
326 | radix_tree_tag_clear(&nfsi->nfs_page_tree, | ||
327 | req->wb_index, NFS_PAGE_TAG_DIRTY); | ||
328 | nfsi->ndirty--; | ||
329 | nfs_list_remove_request(req); | ||
330 | nfs_list_add_request(req, dst); | ||
331 | res++; | ||
332 | if (res == LONG_MAX) | ||
333 | goto out; | ||
334 | next: | ||
310 | idx_start = req->wb_index + 1; | 335 | idx_start = req->wb_index + 1; |
311 | |||
312 | if (nfs_set_page_writeback_locked(req)) { | ||
313 | radix_tree_tag_clear(&nfsi->nfs_page_tree, | ||
314 | req->wb_index, NFS_PAGE_TAG_DIRTY); | ||
315 | nfs_list_remove_request(req); | ||
316 | nfs_list_add_request(req, dst); | ||
317 | dec_zone_page_state(req->wb_page, NR_FILE_DIRTY); | ||
318 | res++; | ||
319 | } | ||
320 | } | 336 | } |
321 | } | 337 | } |
322 | out: | 338 | out: |
339 | WARN_ON ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)); | ||
323 | return res; | 340 | return res; |
324 | } | 341 | } |
325 | 342 | ||
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 4529cc4f3f8f..10f5e80ca157 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c | |||
@@ -215,32 +215,6 @@ static int nfs_proc_read(struct nfs_read_data *rdata) | |||
215 | return status; | 215 | return status; |
216 | } | 216 | } |
217 | 217 | ||
218 | static int nfs_proc_write(struct nfs_write_data *wdata) | ||
219 | { | ||
220 | int flags = wdata->flags; | ||
221 | struct inode * inode = wdata->inode; | ||
222 | struct nfs_fattr * fattr = wdata->res.fattr; | ||
223 | struct rpc_message msg = { | ||
224 | .rpc_proc = &nfs_procedures[NFSPROC_WRITE], | ||
225 | .rpc_argp = &wdata->args, | ||
226 | .rpc_resp = &wdata->res, | ||
227 | .rpc_cred = wdata->cred, | ||
228 | }; | ||
229 | int status; | ||
230 | |||
231 | dprintk("NFS call write %d @ %Ld\n", wdata->args.count, | ||
232 | (long long) wdata->args.offset); | ||
233 | nfs_fattr_init(fattr); | ||
234 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags); | ||
235 | if (status >= 0) { | ||
236 | nfs_post_op_update_inode(inode, fattr); | ||
237 | wdata->res.count = wdata->args.count; | ||
238 | wdata->verf.committed = NFS_FILE_SYNC; | ||
239 | } | ||
240 | dprintk("NFS reply write: %d\n", status); | ||
241 | return status < 0? status : wdata->res.count; | ||
242 | } | ||
243 | |||
244 | static int | 218 | static int |
245 | nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | 219 | nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, |
246 | int flags, struct nameidata *nd) | 220 | int flags, struct nameidata *nd) |
@@ -545,13 +519,10 @@ nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
545 | }; | 519 | }; |
546 | int status; | 520 | int status; |
547 | 521 | ||
548 | lock_kernel(); | ||
549 | |||
550 | dprintk("NFS call readdir %d\n", (unsigned int)cookie); | 522 | dprintk("NFS call readdir %d\n", (unsigned int)cookie); |
551 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 523 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
552 | 524 | ||
553 | dprintk("NFS reply readdir: %d\n", status); | 525 | dprintk("NFS reply readdir: %d\n", status); |
554 | unlock_kernel(); | ||
555 | return status; | 526 | return status; |
556 | } | 527 | } |
557 | 528 | ||
@@ -696,8 +667,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = { | |||
696 | .access = NULL, /* access */ | 667 | .access = NULL, /* access */ |
697 | .readlink = nfs_proc_readlink, | 668 | .readlink = nfs_proc_readlink, |
698 | .read = nfs_proc_read, | 669 | .read = nfs_proc_read, |
699 | .write = nfs_proc_write, | ||
700 | .commit = NULL, /* commit */ | ||
701 | .create = nfs_proc_create, | 670 | .create = nfs_proc_create, |
702 | .remove = nfs_proc_remove, | 671 | .remove = nfs_proc_remove, |
703 | .unlink_setup = nfs_proc_unlink_setup, | 672 | .unlink_setup = nfs_proc_unlink_setup, |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index c2e49c397a27..a9c26521a9e2 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <asm/system.h> | 31 | #include <asm/system.h> |
32 | 32 | ||
33 | #include "internal.h" | ||
33 | #include "iostat.h" | 34 | #include "iostat.h" |
34 | 35 | ||
35 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 36 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
@@ -38,7 +39,7 @@ static int nfs_pagein_one(struct list_head *, struct inode *); | |||
38 | static const struct rpc_call_ops nfs_read_partial_ops; | 39 | static const struct rpc_call_ops nfs_read_partial_ops; |
39 | static const struct rpc_call_ops nfs_read_full_ops; | 40 | static const struct rpc_call_ops nfs_read_full_ops; |
40 | 41 | ||
41 | static kmem_cache_t *nfs_rdata_cachep; | 42 | static struct kmem_cache *nfs_rdata_cachep; |
42 | static mempool_t *nfs_rdata_mempool; | 43 | static mempool_t *nfs_rdata_mempool; |
43 | 44 | ||
44 | #define MIN_POOL_READ (32) | 45 | #define MIN_POOL_READ (32) |
@@ -46,7 +47,7 @@ static mempool_t *nfs_rdata_mempool; | |||
46 | struct nfs_read_data *nfs_readdata_alloc(size_t len) | 47 | struct nfs_read_data *nfs_readdata_alloc(size_t len) |
47 | { | 48 | { |
48 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 49 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
49 | struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, SLAB_NOFS); | 50 | struct nfs_read_data *p = mempool_alloc(nfs_rdata_mempool, GFP_NOFS); |
50 | 51 | ||
51 | if (p) { | 52 | if (p) { |
52 | memset(p, 0, sizeof(*p)); | 53 | memset(p, 0, sizeof(*p)); |
@@ -65,32 +66,22 @@ struct nfs_read_data *nfs_readdata_alloc(size_t len) | |||
65 | return p; | 66 | return p; |
66 | } | 67 | } |
67 | 68 | ||
68 | static void nfs_readdata_free(struct nfs_read_data *p) | 69 | static void nfs_readdata_rcu_free(struct rcu_head *head) |
69 | { | 70 | { |
71 | struct nfs_read_data *p = container_of(head, struct nfs_read_data, task.u.tk_rcu); | ||
70 | if (p && (p->pagevec != &p->page_array[0])) | 72 | if (p && (p->pagevec != &p->page_array[0])) |
71 | kfree(p->pagevec); | 73 | kfree(p->pagevec); |
72 | mempool_free(p, nfs_rdata_mempool); | 74 | mempool_free(p, nfs_rdata_mempool); |
73 | } | 75 | } |
74 | 76 | ||
75 | void nfs_readdata_release(void *data) | 77 | static void nfs_readdata_free(struct nfs_read_data *rdata) |
76 | { | 78 | { |
77 | nfs_readdata_free(data); | 79 | call_rcu_bh(&rdata->task.u.tk_rcu, nfs_readdata_rcu_free); |
78 | } | 80 | } |
79 | 81 | ||
80 | static | 82 | void nfs_readdata_release(void *data) |
81 | unsigned int nfs_page_length(struct inode *inode, struct page *page) | ||
82 | { | 83 | { |
83 | loff_t i_size = i_size_read(inode); | 84 | nfs_readdata_free(data); |
84 | unsigned long idx; | ||
85 | |||
86 | if (i_size <= 0) | ||
87 | return 0; | ||
88 | idx = (i_size - 1) >> PAGE_CACHE_SHIFT; | ||
89 | if (page->index > idx) | ||
90 | return 0; | ||
91 | if (page->index != idx) | ||
92 | return PAGE_CACHE_SIZE; | ||
93 | return 1 + ((i_size - 1) & (PAGE_CACHE_SIZE - 1)); | ||
94 | } | 85 | } |
95 | 86 | ||
96 | static | 87 | static |
@@ -139,12 +130,12 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
139 | { | 130 | { |
140 | unsigned int rsize = NFS_SERVER(inode)->rsize; | 131 | unsigned int rsize = NFS_SERVER(inode)->rsize; |
141 | unsigned int count = PAGE_CACHE_SIZE; | 132 | unsigned int count = PAGE_CACHE_SIZE; |
142 | int result; | 133 | int result = -ENOMEM; |
143 | struct nfs_read_data *rdata; | 134 | struct nfs_read_data *rdata; |
144 | 135 | ||
145 | rdata = nfs_readdata_alloc(count); | 136 | rdata = nfs_readdata_alloc(count); |
146 | if (!rdata) | 137 | if (!rdata) |
147 | return -ENOMEM; | 138 | goto out_unlock; |
148 | 139 | ||
149 | memset(rdata, 0, sizeof(*rdata)); | 140 | memset(rdata, 0, sizeof(*rdata)); |
150 | rdata->flags = (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); | 141 | rdata->flags = (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); |
@@ -212,8 +203,9 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
212 | result = 0; | 203 | result = 0; |
213 | 204 | ||
214 | io_error: | 205 | io_error: |
215 | unlock_page(page); | ||
216 | nfs_readdata_free(rdata); | 206 | nfs_readdata_free(rdata); |
207 | out_unlock: | ||
208 | unlock_page(page); | ||
217 | return result; | 209 | return result; |
218 | } | 210 | } |
219 | 211 | ||
@@ -224,7 +216,7 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, | |||
224 | struct nfs_page *new; | 216 | struct nfs_page *new; |
225 | unsigned int len; | 217 | unsigned int len; |
226 | 218 | ||
227 | len = nfs_page_length(inode, page); | 219 | len = nfs_page_length(page); |
228 | if (len == 0) | 220 | if (len == 0) |
229 | return nfs_return_empty_page(page); | 221 | return nfs_return_empty_page(page); |
230 | new = nfs_create_request(ctx, inode, page, 0, len); | 222 | new = nfs_create_request(ctx, inode, page, 0, len); |
@@ -316,9 +308,7 @@ static void nfs_execute_read(struct nfs_read_data *data) | |||
316 | sigset_t oldset; | 308 | sigset_t oldset; |
317 | 309 | ||
318 | rpc_clnt_sigmask(clnt, &oldset); | 310 | rpc_clnt_sigmask(clnt, &oldset); |
319 | lock_kernel(); | ||
320 | rpc_execute(&data->task); | 311 | rpc_execute(&data->task); |
321 | unlock_kernel(); | ||
322 | rpc_clnt_sigunmask(clnt, &oldset); | 312 | rpc_clnt_sigunmask(clnt, &oldset); |
323 | } | 313 | } |
324 | 314 | ||
@@ -455,6 +445,55 @@ nfs_pagein_list(struct list_head *head, int rpages) | |||
455 | } | 445 | } |
456 | 446 | ||
457 | /* | 447 | /* |
448 | * This is the callback from RPC telling us whether a reply was | ||
449 | * received or some error occurred (timeout or socket shutdown). | ||
450 | */ | ||
451 | int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data) | ||
452 | { | ||
453 | int status; | ||
454 | |||
455 | dprintk("%s: %4d, (status %d)\n", __FUNCTION__, task->tk_pid, | ||
456 | task->tk_status); | ||
457 | |||
458 | status = NFS_PROTO(data->inode)->read_done(task, data); | ||
459 | if (status != 0) | ||
460 | return status; | ||
461 | |||
462 | nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, data->res.count); | ||
463 | |||
464 | if (task->tk_status == -ESTALE) { | ||
465 | set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode)); | ||
466 | nfs_mark_for_revalidate(data->inode); | ||
467 | } | ||
468 | spin_lock(&data->inode->i_lock); | ||
469 | NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME; | ||
470 | spin_unlock(&data->inode->i_lock); | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static int nfs_readpage_retry(struct rpc_task *task, struct nfs_read_data *data) | ||
475 | { | ||
476 | struct nfs_readargs *argp = &data->args; | ||
477 | struct nfs_readres *resp = &data->res; | ||
478 | |||
479 | if (resp->eof || resp->count == argp->count) | ||
480 | return 0; | ||
481 | |||
482 | /* This is a short read! */ | ||
483 | nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); | ||
484 | /* Has the server at least made some progress? */ | ||
485 | if (resp->count == 0) | ||
486 | return 0; | ||
487 | |||
488 | /* Yes, so retry the read at the end of the data */ | ||
489 | argp->offset += resp->count; | ||
490 | argp->pgbase += resp->count; | ||
491 | argp->count -= resp->count; | ||
492 | rpc_restart_call(task); | ||
493 | return -EAGAIN; | ||
494 | } | ||
495 | |||
496 | /* | ||
458 | * Handle a read reply that fills part of a page. | 497 | * Handle a read reply that fills part of a page. |
459 | */ | 498 | */ |
460 | static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata) | 499 | static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata) |
@@ -463,12 +502,16 @@ static void nfs_readpage_result_partial(struct rpc_task *task, void *calldata) | |||
463 | struct nfs_page *req = data->req; | 502 | struct nfs_page *req = data->req; |
464 | struct page *page = req->wb_page; | 503 | struct page *page = req->wb_page; |
465 | 504 | ||
466 | if (likely(task->tk_status >= 0)) | ||
467 | nfs_readpage_truncate_uninitialised_page(data); | ||
468 | else | ||
469 | SetPageError(page); | ||
470 | if (nfs_readpage_result(task, data) != 0) | 505 | if (nfs_readpage_result(task, data) != 0) |
471 | return; | 506 | return; |
507 | |||
508 | if (likely(task->tk_status >= 0)) { | ||
509 | nfs_readpage_truncate_uninitialised_page(data); | ||
510 | if (nfs_readpage_retry(task, data) != 0) | ||
511 | return; | ||
512 | } | ||
513 | if (unlikely(task->tk_status < 0)) | ||
514 | SetPageError(page); | ||
472 | if (atomic_dec_and_test(&req->wb_complete)) { | 515 | if (atomic_dec_and_test(&req->wb_complete)) { |
473 | if (!PageError(page)) | 516 | if (!PageError(page)) |
474 | SetPageUptodate(page); | 517 | SetPageUptodate(page); |
@@ -496,25 +539,13 @@ static void nfs_readpage_set_pages_uptodate(struct nfs_read_data *data) | |||
496 | count += base; | 539 | count += base; |
497 | for (;count >= PAGE_CACHE_SIZE; count -= PAGE_CACHE_SIZE, pages++) | 540 | for (;count >= PAGE_CACHE_SIZE; count -= PAGE_CACHE_SIZE, pages++) |
498 | SetPageUptodate(*pages); | 541 | SetPageUptodate(*pages); |
499 | if (count != 0) | 542 | if (count == 0) |
543 | return; | ||
544 | /* Was this a short read? */ | ||
545 | if (data->res.eof || data->res.count == data->args.count) | ||
500 | SetPageUptodate(*pages); | 546 | SetPageUptodate(*pages); |
501 | } | 547 | } |
502 | 548 | ||
503 | static void nfs_readpage_set_pages_error(struct nfs_read_data *data) | ||
504 | { | ||
505 | unsigned int count = data->args.count; | ||
506 | unsigned int base = data->args.pgbase; | ||
507 | struct page **pages; | ||
508 | |||
509 | pages = &data->args.pages[base >> PAGE_CACHE_SHIFT]; | ||
510 | base &= ~PAGE_CACHE_MASK; | ||
511 | count += base; | ||
512 | for (;count >= PAGE_CACHE_SIZE; count -= PAGE_CACHE_SIZE, pages++) | ||
513 | SetPageError(*pages); | ||
514 | if (count != 0) | ||
515 | SetPageError(*pages); | ||
516 | } | ||
517 | |||
518 | /* | 549 | /* |
519 | * This is the callback from RPC telling us whether a reply was | 550 | * This is the callback from RPC telling us whether a reply was |
520 | * received or some error occurred (timeout or socket shutdown). | 551 | * received or some error occurred (timeout or socket shutdown). |
@@ -523,19 +554,20 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata) | |||
523 | { | 554 | { |
524 | struct nfs_read_data *data = calldata; | 555 | struct nfs_read_data *data = calldata; |
525 | 556 | ||
557 | if (nfs_readpage_result(task, data) != 0) | ||
558 | return; | ||
526 | /* | 559 | /* |
527 | * Note: nfs_readpage_result may change the values of | 560 | * Note: nfs_readpage_retry may change the values of |
528 | * data->args. In the multi-page case, we therefore need | 561 | * data->args. In the multi-page case, we therefore need |
529 | * to ensure that we call the next nfs_readpage_set_page_uptodate() | 562 | * to ensure that we call nfs_readpage_set_pages_uptodate() |
530 | * first in the multi-page case. | 563 | * first. |
531 | */ | 564 | */ |
532 | if (likely(task->tk_status >= 0)) { | 565 | if (likely(task->tk_status >= 0)) { |
533 | nfs_readpage_truncate_uninitialised_page(data); | 566 | nfs_readpage_truncate_uninitialised_page(data); |
534 | nfs_readpage_set_pages_uptodate(data); | 567 | nfs_readpage_set_pages_uptodate(data); |
535 | } else | 568 | if (nfs_readpage_retry(task, data) != 0) |
536 | nfs_readpage_set_pages_error(data); | 569 | return; |
537 | if (nfs_readpage_result(task, data) != 0) | 570 | } |
538 | return; | ||
539 | while (!list_empty(&data->pages)) { | 571 | while (!list_empty(&data->pages)) { |
540 | struct nfs_page *req = nfs_list_entry(data->pages.next); | 572 | struct nfs_page *req = nfs_list_entry(data->pages.next); |
541 | 573 | ||
@@ -550,50 +582,6 @@ static const struct rpc_call_ops nfs_read_full_ops = { | |||
550 | }; | 582 | }; |
551 | 583 | ||
552 | /* | 584 | /* |
553 | * This is the callback from RPC telling us whether a reply was | ||
554 | * received or some error occurred (timeout or socket shutdown). | ||
555 | */ | ||
556 | int nfs_readpage_result(struct rpc_task *task, struct nfs_read_data *data) | ||
557 | { | ||
558 | struct nfs_readargs *argp = &data->args; | ||
559 | struct nfs_readres *resp = &data->res; | ||
560 | int status; | ||
561 | |||
562 | dprintk("NFS: %4d nfs_readpage_result, (status %d)\n", | ||
563 | task->tk_pid, task->tk_status); | ||
564 | |||
565 | status = NFS_PROTO(data->inode)->read_done(task, data); | ||
566 | if (status != 0) | ||
567 | return status; | ||
568 | |||
569 | nfs_add_stats(data->inode, NFSIOS_SERVERREADBYTES, resp->count); | ||
570 | |||
571 | if (task->tk_status < 0) { | ||
572 | if (task->tk_status == -ESTALE) { | ||
573 | set_bit(NFS_INO_STALE, &NFS_FLAGS(data->inode)); | ||
574 | nfs_mark_for_revalidate(data->inode); | ||
575 | } | ||
576 | } else if (resp->count < argp->count && !resp->eof) { | ||
577 | /* This is a short read! */ | ||
578 | nfs_inc_stats(data->inode, NFSIOS_SHORTREAD); | ||
579 | /* Has the server at least made some progress? */ | ||
580 | if (resp->count != 0) { | ||
581 | /* Yes, so retry the read at the end of the data */ | ||
582 | argp->offset += resp->count; | ||
583 | argp->pgbase += resp->count; | ||
584 | argp->count -= resp->count; | ||
585 | rpc_restart_call(task); | ||
586 | return -EAGAIN; | ||
587 | } | ||
588 | task->tk_status = -EIO; | ||
589 | } | ||
590 | spin_lock(&data->inode->i_lock); | ||
591 | NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME; | ||
592 | spin_unlock(&data->inode->i_lock); | ||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * Read a page over NFS. | 585 | * Read a page over NFS. |
598 | * We read the page synchronously in the following case: | 586 | * We read the page synchronously in the following case: |
599 | * - The error flag is set for this page. This happens only when a | 587 | * - The error flag is set for this page. This happens only when a |
@@ -626,9 +614,10 @@ int nfs_readpage(struct file *file, struct page *page) | |||
626 | goto out_error; | 614 | goto out_error; |
627 | 615 | ||
628 | if (file == NULL) { | 616 | if (file == NULL) { |
617 | error = -EBADF; | ||
629 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); | 618 | ctx = nfs_find_open_context(inode, NULL, FMODE_READ); |
630 | if (ctx == NULL) | 619 | if (ctx == NULL) |
631 | return -EBADF; | 620 | goto out_error; |
632 | } else | 621 | } else |
633 | ctx = get_nfs_open_context((struct nfs_open_context *) | 622 | ctx = get_nfs_open_context((struct nfs_open_context *) |
634 | file->private_data); | 623 | file->private_data); |
@@ -663,7 +652,7 @@ readpage_async_filler(void *data, struct page *page) | |||
663 | unsigned int len; | 652 | unsigned int len; |
664 | 653 | ||
665 | nfs_wb_page(inode, page); | 654 | nfs_wb_page(inode, page); |
666 | len = nfs_page_length(inode, page); | 655 | len = nfs_page_length(page); |
667 | if (len == 0) | 656 | if (len == 0) |
668 | return nfs_return_empty_page(page); | 657 | return nfs_return_empty_page(page); |
669 | new = nfs_create_request(desc->ctx, inode, page, 0, len); | 658 | new = nfs_create_request(desc->ctx, inode, page, 0, len); |
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 600bbe630abd..6c686112cc03 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c | |||
@@ -33,9 +33,7 @@ static int nfs_symlink_filler(struct inode *inode, struct page *page) | |||
33 | { | 33 | { |
34 | int error; | 34 | int error; |
35 | 35 | ||
36 | lock_kernel(); | ||
37 | error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE); | 36 | error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE); |
38 | unlock_kernel(); | ||
39 | if (error < 0) | 37 | if (error < 0) |
40 | goto error; | 38 | goto error; |
41 | SetPageUptodate(page); | 39 | SetPageUptodate(page); |
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c index 2fe3403c2409..3ea50ac64820 100644 --- a/fs/nfs/sysctl.c +++ b/fs/nfs/sysctl.c | |||
@@ -18,11 +18,6 @@ | |||
18 | static const int nfs_set_port_min = 0; | 18 | static const int nfs_set_port_min = 0; |
19 | static const int nfs_set_port_max = 65535; | 19 | static const int nfs_set_port_max = 65535; |
20 | static struct ctl_table_header *nfs_callback_sysctl_table; | 20 | static struct ctl_table_header *nfs_callback_sysctl_table; |
21 | /* | ||
22 | * Something that isn't CTL_ANY, CTL_NONE or a value that may clash. | ||
23 | * Use the same values as fs/lockd/svc.c | ||
24 | */ | ||
25 | #define CTL_UNNUMBERED -2 | ||
26 | 21 | ||
27 | static ctl_table nfs_cb_sysctls[] = { | 22 | static ctl_table nfs_cb_sysctls[] = { |
28 | #ifdef CONFIG_NFS_V4 | 23 | #ifdef CONFIG_NFS_V4 |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 883dd4a1c157..594eb16879ef 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <linux/smp_lock.h> | 63 | #include <linux/smp_lock.h> |
64 | 64 | ||
65 | #include "delegation.h" | 65 | #include "delegation.h" |
66 | #include "internal.h" | ||
66 | #include "iostat.h" | 67 | #include "iostat.h" |
67 | 68 | ||
68 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE | 69 | #define NFSDBG_FACILITY NFSDBG_PAGECACHE |
@@ -74,18 +75,17 @@ | |||
74 | * Local function declarations | 75 | * Local function declarations |
75 | */ | 76 | */ |
76 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, | 77 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, |
77 | struct inode *, | ||
78 | struct page *, | 78 | struct page *, |
79 | unsigned int, unsigned int); | 79 | unsigned int, unsigned int); |
80 | static void nfs_mark_request_dirty(struct nfs_page *req); | ||
80 | static int nfs_wait_on_write_congestion(struct address_space *, int); | 81 | static int nfs_wait_on_write_congestion(struct address_space *, int); |
81 | static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int); | 82 | static int nfs_wait_on_requests(struct inode *, unsigned long, unsigned int); |
82 | static int nfs_flush_inode(struct inode *inode, unsigned long idx_start, | 83 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); |
83 | unsigned int npages, int how); | ||
84 | static const struct rpc_call_ops nfs_write_partial_ops; | 84 | static const struct rpc_call_ops nfs_write_partial_ops; |
85 | static const struct rpc_call_ops nfs_write_full_ops; | 85 | static const struct rpc_call_ops nfs_write_full_ops; |
86 | static const struct rpc_call_ops nfs_commit_ops; | 86 | static const struct rpc_call_ops nfs_commit_ops; |
87 | 87 | ||
88 | static kmem_cache_t *nfs_wdata_cachep; | 88 | static struct kmem_cache *nfs_wdata_cachep; |
89 | static mempool_t *nfs_wdata_mempool; | 89 | static mempool_t *nfs_wdata_mempool; |
90 | static mempool_t *nfs_commit_mempool; | 90 | static mempool_t *nfs_commit_mempool; |
91 | 91 | ||
@@ -93,7 +93,7 @@ static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion); | |||
93 | 93 | ||
94 | struct nfs_write_data *nfs_commit_alloc(void) | 94 | struct nfs_write_data *nfs_commit_alloc(void) |
95 | { | 95 | { |
96 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, SLAB_NOFS); | 96 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); |
97 | 97 | ||
98 | if (p) { | 98 | if (p) { |
99 | memset(p, 0, sizeof(*p)); | 99 | memset(p, 0, sizeof(*p)); |
@@ -102,17 +102,23 @@ struct nfs_write_data *nfs_commit_alloc(void) | |||
102 | return p; | 102 | return p; |
103 | } | 103 | } |
104 | 104 | ||
105 | void nfs_commit_free(struct nfs_write_data *p) | 105 | void nfs_commit_rcu_free(struct rcu_head *head) |
106 | { | 106 | { |
107 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
107 | if (p && (p->pagevec != &p->page_array[0])) | 108 | if (p && (p->pagevec != &p->page_array[0])) |
108 | kfree(p->pagevec); | 109 | kfree(p->pagevec); |
109 | mempool_free(p, nfs_commit_mempool); | 110 | mempool_free(p, nfs_commit_mempool); |
110 | } | 111 | } |
111 | 112 | ||
113 | void nfs_commit_free(struct nfs_write_data *wdata) | ||
114 | { | ||
115 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_commit_rcu_free); | ||
116 | } | ||
117 | |||
112 | struct nfs_write_data *nfs_writedata_alloc(size_t len) | 118 | struct nfs_write_data *nfs_writedata_alloc(size_t len) |
113 | { | 119 | { |
114 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; | 120 | unsigned int pagecount = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; |
115 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, SLAB_NOFS); | 121 | struct nfs_write_data *p = mempool_alloc(nfs_wdata_mempool, GFP_NOFS); |
116 | 122 | ||
117 | if (p) { | 123 | if (p) { |
118 | memset(p, 0, sizeof(*p)); | 124 | memset(p, 0, sizeof(*p)); |
@@ -131,18 +137,47 @@ struct nfs_write_data *nfs_writedata_alloc(size_t len) | |||
131 | return p; | 137 | return p; |
132 | } | 138 | } |
133 | 139 | ||
134 | static void nfs_writedata_free(struct nfs_write_data *p) | 140 | static void nfs_writedata_rcu_free(struct rcu_head *head) |
135 | { | 141 | { |
142 | struct nfs_write_data *p = container_of(head, struct nfs_write_data, task.u.tk_rcu); | ||
136 | if (p && (p->pagevec != &p->page_array[0])) | 143 | if (p && (p->pagevec != &p->page_array[0])) |
137 | kfree(p->pagevec); | 144 | kfree(p->pagevec); |
138 | mempool_free(p, nfs_wdata_mempool); | 145 | mempool_free(p, nfs_wdata_mempool); |
139 | } | 146 | } |
140 | 147 | ||
148 | static void nfs_writedata_free(struct nfs_write_data *wdata) | ||
149 | { | ||
150 | call_rcu_bh(&wdata->task.u.tk_rcu, nfs_writedata_rcu_free); | ||
151 | } | ||
152 | |||
141 | void nfs_writedata_release(void *wdata) | 153 | void nfs_writedata_release(void *wdata) |
142 | { | 154 | { |
143 | nfs_writedata_free(wdata); | 155 | nfs_writedata_free(wdata); |
144 | } | 156 | } |
145 | 157 | ||
158 | static struct nfs_page *nfs_page_find_request_locked(struct page *page) | ||
159 | { | ||
160 | struct nfs_page *req = NULL; | ||
161 | |||
162 | if (PagePrivate(page)) { | ||
163 | req = (struct nfs_page *)page_private(page); | ||
164 | if (req != NULL) | ||
165 | atomic_inc(&req->wb_count); | ||
166 | } | ||
167 | return req; | ||
168 | } | ||
169 | |||
170 | static struct nfs_page *nfs_page_find_request(struct page *page) | ||
171 | { | ||
172 | struct nfs_page *req = NULL; | ||
173 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | ||
174 | |||
175 | spin_lock(req_lock); | ||
176 | req = nfs_page_find_request_locked(page); | ||
177 | spin_unlock(req_lock); | ||
178 | return req; | ||
179 | } | ||
180 | |||
146 | /* Adjust the file length if we're writing beyond the end */ | 181 | /* Adjust the file length if we're writing beyond the end */ |
147 | static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) | 182 | static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) |
148 | { | 183 | { |
@@ -164,113 +199,34 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c | |||
164 | */ | 199 | */ |
165 | static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count) | 200 | static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count) |
166 | { | 201 | { |
167 | loff_t end_offs; | ||
168 | |||
169 | if (PageUptodate(page)) | 202 | if (PageUptodate(page)) |
170 | return; | 203 | return; |
171 | if (base != 0) | 204 | if (base != 0) |
172 | return; | 205 | return; |
173 | if (count == PAGE_CACHE_SIZE) { | 206 | if (count != nfs_page_length(page)) |
174 | SetPageUptodate(page); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | end_offs = i_size_read(page->mapping->host) - 1; | ||
179 | if (end_offs < 0) | ||
180 | return; | 207 | return; |
181 | /* Is this the last page? */ | 208 | if (count != PAGE_CACHE_SIZE) |
182 | if (page->index != (unsigned long)(end_offs >> PAGE_CACHE_SHIFT)) | ||
183 | return; | ||
184 | /* This is the last page: set PG_uptodate if we cover the entire | ||
185 | * extent of the data, then zero the rest of the page. | ||
186 | */ | ||
187 | if (count == (unsigned int)(end_offs & (PAGE_CACHE_SIZE - 1)) + 1) { | ||
188 | memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count); | 209 | memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count); |
189 | SetPageUptodate(page); | 210 | SetPageUptodate(page); |
190 | } | ||
191 | } | 211 | } |
192 | 212 | ||
193 | /* | 213 | static int nfs_writepage_setup(struct nfs_open_context *ctx, struct page *page, |
194 | * Write a page synchronously. | ||
195 | * Offset is the data offset within the page. | ||
196 | */ | ||
197 | static int nfs_writepage_sync(struct nfs_open_context *ctx, struct inode *inode, | ||
198 | struct page *page, unsigned int offset, unsigned int count, | ||
199 | int how) | ||
200 | { | ||
201 | unsigned int wsize = NFS_SERVER(inode)->wsize; | ||
202 | int result, written = 0; | ||
203 | struct nfs_write_data *wdata; | ||
204 | |||
205 | wdata = nfs_writedata_alloc(wsize); | ||
206 | if (!wdata) | ||
207 | return -ENOMEM; | ||
208 | |||
209 | wdata->flags = how; | ||
210 | wdata->cred = ctx->cred; | ||
211 | wdata->inode = inode; | ||
212 | wdata->args.fh = NFS_FH(inode); | ||
213 | wdata->args.context = ctx; | ||
214 | wdata->args.pages = &page; | ||
215 | wdata->args.stable = NFS_FILE_SYNC; | ||
216 | wdata->args.pgbase = offset; | ||
217 | wdata->args.count = wsize; | ||
218 | wdata->res.fattr = &wdata->fattr; | ||
219 | wdata->res.verf = &wdata->verf; | ||
220 | |||
221 | dprintk("NFS: nfs_writepage_sync(%s/%Ld %d@%Ld)\n", | ||
222 | inode->i_sb->s_id, | ||
223 | (long long)NFS_FILEID(inode), | ||
224 | count, (long long)(page_offset(page) + offset)); | ||
225 | |||
226 | set_page_writeback(page); | ||
227 | nfs_begin_data_update(inode); | ||
228 | do { | ||
229 | if (count < wsize) | ||
230 | wdata->args.count = count; | ||
231 | wdata->args.offset = page_offset(page) + wdata->args.pgbase; | ||
232 | |||
233 | result = NFS_PROTO(inode)->write(wdata); | ||
234 | |||
235 | if (result < 0) { | ||
236 | /* Must mark the page invalid after I/O error */ | ||
237 | ClearPageUptodate(page); | ||
238 | goto io_error; | ||
239 | } | ||
240 | if (result < wdata->args.count) | ||
241 | printk(KERN_WARNING "NFS: short write, count=%u, result=%d\n", | ||
242 | wdata->args.count, result); | ||
243 | |||
244 | wdata->args.offset += result; | ||
245 | wdata->args.pgbase += result; | ||
246 | written += result; | ||
247 | count -= result; | ||
248 | nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, result); | ||
249 | } while (count); | ||
250 | /* Update file length */ | ||
251 | nfs_grow_file(page, offset, written); | ||
252 | /* Set the PG_uptodate flag? */ | ||
253 | nfs_mark_uptodate(page, offset, written); | ||
254 | |||
255 | if (PageError(page)) | ||
256 | ClearPageError(page); | ||
257 | |||
258 | io_error: | ||
259 | nfs_end_data_update(inode); | ||
260 | end_page_writeback(page); | ||
261 | nfs_writedata_free(wdata); | ||
262 | return written ? written : result; | ||
263 | } | ||
264 | |||
265 | static int nfs_writepage_async(struct nfs_open_context *ctx, | ||
266 | struct inode *inode, struct page *page, | ||
267 | unsigned int offset, unsigned int count) | 214 | unsigned int offset, unsigned int count) |
268 | { | 215 | { |
269 | struct nfs_page *req; | 216 | struct nfs_page *req; |
217 | int ret; | ||
270 | 218 | ||
271 | req = nfs_update_request(ctx, inode, page, offset, count); | 219 | for (;;) { |
272 | if (IS_ERR(req)) | 220 | req = nfs_update_request(ctx, page, offset, count); |
273 | return PTR_ERR(req); | 221 | if (!IS_ERR(req)) |
222 | break; | ||
223 | ret = PTR_ERR(req); | ||
224 | if (ret != -EBUSY) | ||
225 | return ret; | ||
226 | ret = nfs_wb_page(page->mapping->host, page); | ||
227 | if (ret != 0) | ||
228 | return ret; | ||
229 | } | ||
274 | /* Update file length */ | 230 | /* Update file length */ |
275 | nfs_grow_file(page, offset, count); | 231 | nfs_grow_file(page, offset, count); |
276 | /* Set the PG_uptodate flag? */ | 232 | /* Set the PG_uptodate flag? */ |
@@ -289,73 +245,94 @@ static int wb_priority(struct writeback_control *wbc) | |||
289 | } | 245 | } |
290 | 246 | ||
291 | /* | 247 | /* |
248 | * Find an associated nfs write request, and prepare to flush it out | ||
249 | * Returns 1 if there was no write request, or if the request was | ||
250 | * already tagged by nfs_set_page_dirty.Returns 0 if the request | ||
251 | * was not tagged. | ||
252 | * May also return an error if the user signalled nfs_wait_on_request(). | ||
253 | */ | ||
254 | static int nfs_page_mark_flush(struct page *page) | ||
255 | { | ||
256 | struct nfs_page *req; | ||
257 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | ||
258 | int ret; | ||
259 | |||
260 | spin_lock(req_lock); | ||
261 | for(;;) { | ||
262 | req = nfs_page_find_request_locked(page); | ||
263 | if (req == NULL) { | ||
264 | spin_unlock(req_lock); | ||
265 | return 1; | ||
266 | } | ||
267 | if (nfs_lock_request_dontget(req)) | ||
268 | break; | ||
269 | /* Note: If we hold the page lock, as is the case in nfs_writepage, | ||
270 | * then the call to nfs_lock_request_dontget() will always | ||
271 | * succeed provided that someone hasn't already marked the | ||
272 | * request as dirty (in which case we don't care). | ||
273 | */ | ||
274 | spin_unlock(req_lock); | ||
275 | ret = nfs_wait_on_request(req); | ||
276 | nfs_release_request(req); | ||
277 | if (ret != 0) | ||
278 | return ret; | ||
279 | spin_lock(req_lock); | ||
280 | } | ||
281 | spin_unlock(req_lock); | ||
282 | if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { | ||
283 | nfs_mark_request_dirty(req); | ||
284 | set_page_writeback(page); | ||
285 | } | ||
286 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); | ||
287 | nfs_unlock_request(req); | ||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * Write an mmapped page to the server. | 292 | * Write an mmapped page to the server. |
293 | */ | 293 | */ |
294 | int nfs_writepage(struct page *page, struct writeback_control *wbc) | 294 | static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc) |
295 | { | 295 | { |
296 | struct nfs_open_context *ctx; | 296 | struct nfs_open_context *ctx; |
297 | struct inode *inode = page->mapping->host; | 297 | struct inode *inode = page->mapping->host; |
298 | unsigned long end_index; | 298 | unsigned offset; |
299 | unsigned offset = PAGE_CACHE_SIZE; | ||
300 | loff_t i_size = i_size_read(inode); | ||
301 | int inode_referenced = 0; | ||
302 | int priority = wb_priority(wbc); | ||
303 | int err; | 299 | int err; |
304 | 300 | ||
305 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); | 301 | nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE); |
306 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); | 302 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1); |
307 | 303 | ||
308 | /* | 304 | err = nfs_page_mark_flush(page); |
309 | * Note: We need to ensure that we have a reference to the inode | 305 | if (err <= 0) |
310 | * if we are to do asynchronous writes. If not, waiting | 306 | goto out; |
311 | * in nfs_wait_on_request() may deadlock with clear_inode(). | 307 | err = 0; |
312 | * | 308 | offset = nfs_page_length(page); |
313 | * If igrab() fails here, then it is in any case safe to | 309 | if (!offset) |
314 | * call nfs_wb_page(), since there will be no pending writes. | ||
315 | */ | ||
316 | if (igrab(inode) != 0) | ||
317 | inode_referenced = 1; | ||
318 | end_index = i_size >> PAGE_CACHE_SHIFT; | ||
319 | |||
320 | /* Ensure we've flushed out any previous writes */ | ||
321 | nfs_wb_page_priority(inode, page, priority); | ||
322 | |||
323 | /* easy case */ | ||
324 | if (page->index < end_index) | ||
325 | goto do_it; | ||
326 | /* things got complicated... */ | ||
327 | offset = i_size & (PAGE_CACHE_SIZE-1); | ||
328 | |||
329 | /* OK, are we completely out? */ | ||
330 | err = 0; /* potential race with truncate - ignore */ | ||
331 | if (page->index >= end_index+1 || !offset) | ||
332 | goto out; | 310 | goto out; |
333 | do_it: | 311 | |
334 | ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE); | 312 | ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE); |
335 | if (ctx == NULL) { | 313 | if (ctx == NULL) { |
336 | err = -EBADF; | 314 | err = -EBADF; |
337 | goto out; | 315 | goto out; |
338 | } | 316 | } |
339 | lock_kernel(); | 317 | err = nfs_writepage_setup(ctx, page, 0, offset); |
340 | if (!IS_SYNC(inode) && inode_referenced) { | ||
341 | err = nfs_writepage_async(ctx, inode, page, 0, offset); | ||
342 | if (!wbc->for_writepages) | ||
343 | nfs_flush_inode(inode, 0, 0, wb_priority(wbc)); | ||
344 | } else { | ||
345 | err = nfs_writepage_sync(ctx, inode, page, 0, | ||
346 | offset, priority); | ||
347 | if (err >= 0) { | ||
348 | if (err != offset) | ||
349 | redirty_page_for_writepage(wbc, page); | ||
350 | err = 0; | ||
351 | } | ||
352 | } | ||
353 | unlock_kernel(); | ||
354 | put_nfs_open_context(ctx); | 318 | put_nfs_open_context(ctx); |
319 | if (err != 0) | ||
320 | goto out; | ||
321 | err = nfs_page_mark_flush(page); | ||
322 | if (err > 0) | ||
323 | err = 0; | ||
355 | out: | 324 | out: |
325 | if (!wbc->for_writepages) | ||
326 | nfs_flush_mapping(page->mapping, wbc, wb_priority(wbc)); | ||
327 | return err; | ||
328 | } | ||
329 | |||
330 | int nfs_writepage(struct page *page, struct writeback_control *wbc) | ||
331 | { | ||
332 | int err; | ||
333 | |||
334 | err = nfs_writepage_locked(page, wbc); | ||
356 | unlock_page(page); | 335 | unlock_page(page); |
357 | if (inode_referenced) | ||
358 | iput(inode); | ||
359 | return err; | 336 | return err; |
360 | } | 337 | } |
361 | 338 | ||
@@ -379,21 +356,18 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
379 | return 0; | 356 | return 0; |
380 | nfs_wait_on_write_congestion(mapping, 0); | 357 | nfs_wait_on_write_congestion(mapping, 0); |
381 | } | 358 | } |
382 | err = nfs_flush_inode(inode, 0, 0, wb_priority(wbc)); | 359 | err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); |
383 | if (err < 0) | 360 | if (err < 0) |
384 | goto out; | 361 | goto out; |
385 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); | 362 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); |
386 | wbc->nr_to_write -= err; | ||
387 | if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) { | 363 | if (!wbc->nonblocking && wbc->sync_mode == WB_SYNC_ALL) { |
388 | err = nfs_wait_on_requests(inode, 0, 0); | 364 | err = nfs_wait_on_requests(inode, 0, 0); |
389 | if (err < 0) | 365 | if (err < 0) |
390 | goto out; | 366 | goto out; |
391 | } | 367 | } |
392 | err = nfs_commit_inode(inode, wb_priority(wbc)); | 368 | err = nfs_commit_inode(inode, wb_priority(wbc)); |
393 | if (err > 0) { | 369 | if (err > 0) |
394 | wbc->nr_to_write -= err; | ||
395 | err = 0; | 370 | err = 0; |
396 | } | ||
397 | out: | 371 | out: |
398 | clear_bit(BDI_write_congested, &bdi->state); | 372 | clear_bit(BDI_write_congested, &bdi->state); |
399 | wake_up_all(&nfs_write_congestion); | 373 | wake_up_all(&nfs_write_congestion); |
@@ -420,6 +394,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
420 | nfsi->change_attr++; | 394 | nfsi->change_attr++; |
421 | } | 395 | } |
422 | SetPagePrivate(req->wb_page); | 396 | SetPagePrivate(req->wb_page); |
397 | set_page_private(req->wb_page, (unsigned long)req); | ||
423 | nfsi->npages++; | 398 | nfsi->npages++; |
424 | atomic_inc(&req->wb_count); | 399 | atomic_inc(&req->wb_count); |
425 | return 0; | 400 | return 0; |
@@ -436,6 +411,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
436 | BUG_ON (!NFS_WBACK_BUSY(req)); | 411 | BUG_ON (!NFS_WBACK_BUSY(req)); |
437 | 412 | ||
438 | spin_lock(&nfsi->req_lock); | 413 | spin_lock(&nfsi->req_lock); |
414 | set_page_private(req->wb_page, 0); | ||
439 | ClearPagePrivate(req->wb_page); | 415 | ClearPagePrivate(req->wb_page); |
440 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); | 416 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); |
441 | nfsi->npages--; | 417 | nfsi->npages--; |
@@ -450,33 +426,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
450 | } | 426 | } |
451 | 427 | ||
452 | /* | 428 | /* |
453 | * Find a request | ||
454 | */ | ||
455 | static inline struct nfs_page * | ||
456 | _nfs_find_request(struct inode *inode, unsigned long index) | ||
457 | { | ||
458 | struct nfs_inode *nfsi = NFS_I(inode); | ||
459 | struct nfs_page *req; | ||
460 | |||
461 | req = (struct nfs_page*)radix_tree_lookup(&nfsi->nfs_page_tree, index); | ||
462 | if (req) | ||
463 | atomic_inc(&req->wb_count); | ||
464 | return req; | ||
465 | } | ||
466 | |||
467 | static struct nfs_page * | ||
468 | nfs_find_request(struct inode *inode, unsigned long index) | ||
469 | { | ||
470 | struct nfs_page *req; | ||
471 | struct nfs_inode *nfsi = NFS_I(inode); | ||
472 | |||
473 | spin_lock(&nfsi->req_lock); | ||
474 | req = _nfs_find_request(inode, index); | ||
475 | spin_unlock(&nfsi->req_lock); | ||
476 | return req; | ||
477 | } | ||
478 | |||
479 | /* | ||
480 | * Add a request to the inode's dirty list. | 429 | * Add a request to the inode's dirty list. |
481 | */ | 430 | */ |
482 | static void | 431 | static void |
@@ -491,8 +440,14 @@ nfs_mark_request_dirty(struct nfs_page *req) | |||
491 | nfs_list_add_request(req, &nfsi->dirty); | 440 | nfs_list_add_request(req, &nfsi->dirty); |
492 | nfsi->ndirty++; | 441 | nfsi->ndirty++; |
493 | spin_unlock(&nfsi->req_lock); | 442 | spin_unlock(&nfsi->req_lock); |
494 | inc_zone_page_state(req->wb_page, NR_FILE_DIRTY); | 443 | __mark_inode_dirty(inode, I_DIRTY_PAGES); |
495 | mark_inode_dirty(inode); | 444 | } |
445 | |||
446 | static void | ||
447 | nfs_redirty_request(struct nfs_page *req) | ||
448 | { | ||
449 | clear_bit(PG_FLUSHING, &req->wb_flags); | ||
450 | __set_page_dirty_nobuffers(req->wb_page); | ||
496 | } | 451 | } |
497 | 452 | ||
498 | /* | 453 | /* |
@@ -501,8 +456,7 @@ nfs_mark_request_dirty(struct nfs_page *req) | |||
501 | static inline int | 456 | static inline int |
502 | nfs_dirty_request(struct nfs_page *req) | 457 | nfs_dirty_request(struct nfs_page *req) |
503 | { | 458 | { |
504 | struct nfs_inode *nfsi = NFS_I(req->wb_context->dentry->d_inode); | 459 | return test_bit(PG_FLUSHING, &req->wb_flags) == 0; |
505 | return !list_empty(&req->wb_list) && req->wb_list_head == &nfsi->dirty; | ||
506 | } | 460 | } |
507 | 461 | ||
508 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 462 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
@@ -520,7 +474,7 @@ nfs_mark_request_commit(struct nfs_page *req) | |||
520 | nfsi->ncommit++; | 474 | nfsi->ncommit++; |
521 | spin_unlock(&nfsi->req_lock); | 475 | spin_unlock(&nfsi->req_lock); |
522 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | 476 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); |
523 | mark_inode_dirty(inode); | 477 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); |
524 | } | 478 | } |
525 | #endif | 479 | #endif |
526 | 480 | ||
@@ -597,31 +551,6 @@ static void nfs_cancel_commit_list(struct list_head *head) | |||
597 | } | 551 | } |
598 | } | 552 | } |
599 | 553 | ||
600 | /* | ||
601 | * nfs_scan_dirty - Scan an inode for dirty requests | ||
602 | * @inode: NFS inode to scan | ||
603 | * @dst: destination list | ||
604 | * @idx_start: lower bound of page->index to scan. | ||
605 | * @npages: idx_start + npages sets the upper bound to scan. | ||
606 | * | ||
607 | * Moves requests from the inode's dirty page list. | ||
608 | * The requests are *not* checked to ensure that they form a contiguous set. | ||
609 | */ | ||
610 | static int | ||
611 | nfs_scan_dirty(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages) | ||
612 | { | ||
613 | struct nfs_inode *nfsi = NFS_I(inode); | ||
614 | int res = 0; | ||
615 | |||
616 | if (nfsi->ndirty != 0) { | ||
617 | res = nfs_scan_lock_dirty(nfsi, dst, idx_start, npages); | ||
618 | nfsi->ndirty -= res; | ||
619 | if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)) | ||
620 | printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n"); | ||
621 | } | ||
622 | return res; | ||
623 | } | ||
624 | |||
625 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 554 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
626 | /* | 555 | /* |
627 | * nfs_scan_commit - Scan an inode for commit requests | 556 | * nfs_scan_commit - Scan an inode for commit requests |
@@ -698,27 +627,27 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | |||
698 | * Note: Should always be called with the Page Lock held! | 627 | * Note: Should always be called with the Page Lock held! |
699 | */ | 628 | */ |
700 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | 629 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, |
701 | struct inode *inode, struct page *page, | 630 | struct page *page, unsigned int offset, unsigned int bytes) |
702 | unsigned int offset, unsigned int bytes) | ||
703 | { | 631 | { |
704 | struct nfs_server *server = NFS_SERVER(inode); | 632 | struct inode *inode = page->mapping->host; |
705 | struct nfs_inode *nfsi = NFS_I(inode); | 633 | struct nfs_inode *nfsi = NFS_I(inode); |
706 | struct nfs_page *req, *new = NULL; | 634 | struct nfs_page *req, *new = NULL; |
707 | unsigned long rqend, end; | 635 | unsigned long rqend, end; |
708 | 636 | ||
709 | end = offset + bytes; | 637 | end = offset + bytes; |
710 | 638 | ||
711 | if (nfs_wait_on_write_congestion(page->mapping, server->flags & NFS_MOUNT_INTR)) | 639 | if (nfs_wait_on_write_congestion(page->mapping, NFS_SERVER(inode)->flags & NFS_MOUNT_INTR)) |
712 | return ERR_PTR(-ERESTARTSYS); | 640 | return ERR_PTR(-ERESTARTSYS); |
713 | for (;;) { | 641 | for (;;) { |
714 | /* Loop over all inode entries and see if we find | 642 | /* Loop over all inode entries and see if we find |
715 | * A request for the page we wish to update | 643 | * A request for the page we wish to update |
716 | */ | 644 | */ |
717 | spin_lock(&nfsi->req_lock); | 645 | spin_lock(&nfsi->req_lock); |
718 | req = _nfs_find_request(inode, page->index); | 646 | req = nfs_page_find_request_locked(page); |
719 | if (req) { | 647 | if (req) { |
720 | if (!nfs_lock_request_dontget(req)) { | 648 | if (!nfs_lock_request_dontget(req)) { |
721 | int error; | 649 | int error; |
650 | |||
722 | spin_unlock(&nfsi->req_lock); | 651 | spin_unlock(&nfsi->req_lock); |
723 | error = nfs_wait_on_request(req); | 652 | error = nfs_wait_on_request(req); |
724 | nfs_release_request(req); | 653 | nfs_release_request(req); |
@@ -745,7 +674,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
745 | return ERR_PTR(error); | 674 | return ERR_PTR(error); |
746 | } | 675 | } |
747 | spin_unlock(&nfsi->req_lock); | 676 | spin_unlock(&nfsi->req_lock); |
748 | nfs_mark_request_dirty(new); | ||
749 | return new; | 677 | return new; |
750 | } | 678 | } |
751 | spin_unlock(&nfsi->req_lock); | 679 | spin_unlock(&nfsi->req_lock); |
@@ -786,9 +714,8 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | |||
786 | int nfs_flush_incompatible(struct file *file, struct page *page) | 714 | int nfs_flush_incompatible(struct file *file, struct page *page) |
787 | { | 715 | { |
788 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; | 716 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; |
789 | struct inode *inode = page->mapping->host; | ||
790 | struct nfs_page *req; | 717 | struct nfs_page *req; |
791 | int status = 0; | 718 | int do_flush, status; |
792 | /* | 719 | /* |
793 | * Look for a request corresponding to this page. If there | 720 | * Look for a request corresponding to this page. If there |
794 | * is one, and it belongs to another file, we flush it out | 721 | * is one, and it belongs to another file, we flush it out |
@@ -797,13 +724,18 @@ int nfs_flush_incompatible(struct file *file, struct page *page) | |||
797 | * Also do the same if we find a request from an existing | 724 | * Also do the same if we find a request from an existing |
798 | * dropped page. | 725 | * dropped page. |
799 | */ | 726 | */ |
800 | req = nfs_find_request(inode, page->index); | 727 | do { |
801 | if (req) { | 728 | req = nfs_page_find_request(page); |
802 | if (req->wb_page != page || ctx != req->wb_context) | 729 | if (req == NULL) |
803 | status = nfs_wb_page(inode, page); | 730 | return 0; |
731 | do_flush = req->wb_page != page || req->wb_context != ctx | ||
732 | || !nfs_dirty_request(req); | ||
804 | nfs_release_request(req); | 733 | nfs_release_request(req); |
805 | } | 734 | if (!do_flush) |
806 | return (status < 0) ? status : 0; | 735 | return 0; |
736 | status = nfs_wb_page(page->mapping->host, page); | ||
737 | } while (status == 0); | ||
738 | return status; | ||
807 | } | 739 | } |
808 | 740 | ||
809 | /* | 741 | /* |
@@ -817,7 +749,6 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
817 | { | 749 | { |
818 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; | 750 | struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; |
819 | struct inode *inode = page->mapping->host; | 751 | struct inode *inode = page->mapping->host; |
820 | struct nfs_page *req; | ||
821 | int status = 0; | 752 | int status = 0; |
822 | 753 | ||
823 | nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); | 754 | nfs_inc_stats(inode, NFSIOS_VFSUPDATEPAGE); |
@@ -827,62 +758,18 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
827 | file->f_dentry->d_name.name, count, | 758 | file->f_dentry->d_name.name, count, |
828 | (long long)(page_offset(page) +offset)); | 759 | (long long)(page_offset(page) +offset)); |
829 | 760 | ||
830 | if (IS_SYNC(inode)) { | ||
831 | status = nfs_writepage_sync(ctx, inode, page, offset, count, 0); | ||
832 | if (status > 0) { | ||
833 | if (offset == 0 && status == PAGE_CACHE_SIZE) | ||
834 | SetPageUptodate(page); | ||
835 | return 0; | ||
836 | } | ||
837 | return status; | ||
838 | } | ||
839 | |||
840 | /* If we're not using byte range locks, and we know the page | 761 | /* If we're not using byte range locks, and we know the page |
841 | * is entirely in cache, it may be more efficient to avoid | 762 | * is entirely in cache, it may be more efficient to avoid |
842 | * fragmenting write requests. | 763 | * fragmenting write requests. |
843 | */ | 764 | */ |
844 | if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { | 765 | if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) { |
845 | loff_t end_offs = i_size_read(inode) - 1; | 766 | count = max(count + offset, nfs_page_length(page)); |
846 | unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT; | ||
847 | |||
848 | count += offset; | ||
849 | offset = 0; | 767 | offset = 0; |
850 | if (unlikely(end_offs < 0)) { | ||
851 | /* Do nothing */ | ||
852 | } else if (page->index == end_index) { | ||
853 | unsigned int pglen; | ||
854 | pglen = (unsigned int)(end_offs & (PAGE_CACHE_SIZE-1)) + 1; | ||
855 | if (count < pglen) | ||
856 | count = pglen; | ||
857 | } else if (page->index < end_index) | ||
858 | count = PAGE_CACHE_SIZE; | ||
859 | } | 768 | } |
860 | 769 | ||
861 | /* | 770 | status = nfs_writepage_setup(ctx, page, offset, count); |
862 | * Try to find an NFS request corresponding to this page | 771 | __set_page_dirty_nobuffers(page); |
863 | * and update it. | ||
864 | * If the existing request cannot be updated, we must flush | ||
865 | * it out now. | ||
866 | */ | ||
867 | do { | ||
868 | req = nfs_update_request(ctx, inode, page, offset, count); | ||
869 | status = (IS_ERR(req)) ? PTR_ERR(req) : 0; | ||
870 | if (status != -EBUSY) | ||
871 | break; | ||
872 | /* Request could not be updated. Flush it out and try again */ | ||
873 | status = nfs_wb_page(inode, page); | ||
874 | } while (status >= 0); | ||
875 | if (status < 0) | ||
876 | goto done; | ||
877 | |||
878 | status = 0; | ||
879 | 772 | ||
880 | /* Update file length */ | ||
881 | nfs_grow_file(page, offset, count); | ||
882 | /* Set the PG_uptodate flag? */ | ||
883 | nfs_mark_uptodate(page, req->wb_pgbase, req->wb_bytes); | ||
884 | nfs_unlock_request(req); | ||
885 | done: | ||
886 | dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", | 773 | dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", |
887 | status, (long long)i_size_read(inode)); | 774 | status, (long long)i_size_read(inode)); |
888 | if (status < 0) | 775 | if (status < 0) |
@@ -897,7 +784,7 @@ static void nfs_writepage_release(struct nfs_page *req) | |||
897 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 784 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
898 | if (!PageError(req->wb_page)) { | 785 | if (!PageError(req->wb_page)) { |
899 | if (NFS_NEED_RESCHED(req)) { | 786 | if (NFS_NEED_RESCHED(req)) { |
900 | nfs_mark_request_dirty(req); | 787 | nfs_redirty_request(req); |
901 | goto out; | 788 | goto out; |
902 | } else if (NFS_NEED_COMMIT(req)) { | 789 | } else if (NFS_NEED_COMMIT(req)) { |
903 | nfs_mark_request_commit(req); | 790 | nfs_mark_request_commit(req); |
@@ -979,9 +866,7 @@ static void nfs_execute_write(struct nfs_write_data *data) | |||
979 | sigset_t oldset; | 866 | sigset_t oldset; |
980 | 867 | ||
981 | rpc_clnt_sigmask(clnt, &oldset); | 868 | rpc_clnt_sigmask(clnt, &oldset); |
982 | lock_kernel(); | ||
983 | rpc_execute(&data->task); | 869 | rpc_execute(&data->task); |
984 | unlock_kernel(); | ||
985 | rpc_clnt_sigunmask(clnt, &oldset); | 870 | rpc_clnt_sigunmask(clnt, &oldset); |
986 | } | 871 | } |
987 | 872 | ||
@@ -1015,7 +900,6 @@ static int nfs_flush_multi(struct inode *inode, struct list_head *head, int how) | |||
1015 | atomic_set(&req->wb_complete, requests); | 900 | atomic_set(&req->wb_complete, requests); |
1016 | 901 | ||
1017 | ClearPageError(page); | 902 | ClearPageError(page); |
1018 | set_page_writeback(page); | ||
1019 | offset = 0; | 903 | offset = 0; |
1020 | nbytes = req->wb_bytes; | 904 | nbytes = req->wb_bytes; |
1021 | do { | 905 | do { |
@@ -1043,9 +927,9 @@ out_bad: | |||
1043 | while (!list_empty(&list)) { | 927 | while (!list_empty(&list)) { |
1044 | data = list_entry(list.next, struct nfs_write_data, pages); | 928 | data = list_entry(list.next, struct nfs_write_data, pages); |
1045 | list_del(&data->pages); | 929 | list_del(&data->pages); |
1046 | nfs_writedata_free(data); | 930 | nfs_writedata_release(data); |
1047 | } | 931 | } |
1048 | nfs_mark_request_dirty(req); | 932 | nfs_redirty_request(req); |
1049 | nfs_clear_page_writeback(req); | 933 | nfs_clear_page_writeback(req); |
1050 | return -ENOMEM; | 934 | return -ENOMEM; |
1051 | } | 935 | } |
@@ -1076,7 +960,6 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) | |||
1076 | nfs_list_remove_request(req); | 960 | nfs_list_remove_request(req); |
1077 | nfs_list_add_request(req, &data->pages); | 961 | nfs_list_add_request(req, &data->pages); |
1078 | ClearPageError(req->wb_page); | 962 | ClearPageError(req->wb_page); |
1079 | set_page_writeback(req->wb_page); | ||
1080 | *pages++ = req->wb_page; | 963 | *pages++ = req->wb_page; |
1081 | count += req->wb_bytes; | 964 | count += req->wb_bytes; |
1082 | } | 965 | } |
@@ -1091,7 +974,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) | |||
1091 | while (!list_empty(head)) { | 974 | while (!list_empty(head)) { |
1092 | struct nfs_page *req = nfs_list_entry(head->next); | 975 | struct nfs_page *req = nfs_list_entry(head->next); |
1093 | nfs_list_remove_request(req); | 976 | nfs_list_remove_request(req); |
1094 | nfs_mark_request_dirty(req); | 977 | nfs_redirty_request(req); |
1095 | nfs_clear_page_writeback(req); | 978 | nfs_clear_page_writeback(req); |
1096 | } | 979 | } |
1097 | return -ENOMEM; | 980 | return -ENOMEM; |
@@ -1126,7 +1009,7 @@ out_err: | |||
1126 | while (!list_empty(head)) { | 1009 | while (!list_empty(head)) { |
1127 | req = nfs_list_entry(head->next); | 1010 | req = nfs_list_entry(head->next); |
1128 | nfs_list_remove_request(req); | 1011 | nfs_list_remove_request(req); |
1129 | nfs_mark_request_dirty(req); | 1012 | nfs_redirty_request(req); |
1130 | nfs_clear_page_writeback(req); | 1013 | nfs_clear_page_writeback(req); |
1131 | } | 1014 | } |
1132 | return error; | 1015 | return error; |
@@ -1442,7 +1325,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) | |||
1442 | } | 1325 | } |
1443 | /* We have a mismatch. Write the page again */ | 1326 | /* We have a mismatch. Write the page again */ |
1444 | dprintk(" mismatch\n"); | 1327 | dprintk(" mismatch\n"); |
1445 | nfs_mark_request_dirty(req); | 1328 | nfs_redirty_request(req); |
1446 | next: | 1329 | next: |
1447 | nfs_clear_page_writeback(req); | 1330 | nfs_clear_page_writeback(req); |
1448 | } | 1331 | } |
@@ -1459,18 +1342,17 @@ static inline int nfs_commit_list(struct inode *inode, struct list_head *head, i | |||
1459 | } | 1342 | } |
1460 | #endif | 1343 | #endif |
1461 | 1344 | ||
1462 | static int nfs_flush_inode(struct inode *inode, unsigned long idx_start, | 1345 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how) |
1463 | unsigned int npages, int how) | ||
1464 | { | 1346 | { |
1465 | struct nfs_inode *nfsi = NFS_I(inode); | 1347 | struct nfs_inode *nfsi = NFS_I(mapping->host); |
1466 | LIST_HEAD(head); | 1348 | LIST_HEAD(head); |
1467 | int res; | 1349 | long res; |
1468 | 1350 | ||
1469 | spin_lock(&nfsi->req_lock); | 1351 | spin_lock(&nfsi->req_lock); |
1470 | res = nfs_scan_dirty(inode, &head, idx_start, npages); | 1352 | res = nfs_scan_dirty(mapping, wbc, &head); |
1471 | spin_unlock(&nfsi->req_lock); | 1353 | spin_unlock(&nfsi->req_lock); |
1472 | if (res) { | 1354 | if (res) { |
1473 | int error = nfs_flush_list(inode, &head, res, how); | 1355 | int error = nfs_flush_list(mapping->host, &head, res, how); |
1474 | if (error < 0) | 1356 | if (error < 0) |
1475 | return error; | 1357 | return error; |
1476 | } | 1358 | } |
@@ -1496,38 +1378,62 @@ int nfs_commit_inode(struct inode *inode, int how) | |||
1496 | } | 1378 | } |
1497 | #endif | 1379 | #endif |
1498 | 1380 | ||
1499 | int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start, | 1381 | long nfs_sync_mapping_wait(struct address_space *mapping, struct writeback_control *wbc, int how) |
1500 | unsigned int npages, int how) | ||
1501 | { | 1382 | { |
1383 | struct inode *inode = mapping->host; | ||
1502 | struct nfs_inode *nfsi = NFS_I(inode); | 1384 | struct nfs_inode *nfsi = NFS_I(inode); |
1385 | unsigned long idx_start, idx_end; | ||
1386 | unsigned int npages = 0; | ||
1503 | LIST_HEAD(head); | 1387 | LIST_HEAD(head); |
1504 | int nocommit = how & FLUSH_NOCOMMIT; | 1388 | int nocommit = how & FLUSH_NOCOMMIT; |
1505 | int pages, ret; | 1389 | long pages, ret; |
1506 | 1390 | ||
1391 | /* FIXME */ | ||
1392 | if (wbc->range_cyclic) | ||
1393 | idx_start = 0; | ||
1394 | else { | ||
1395 | idx_start = wbc->range_start >> PAGE_CACHE_SHIFT; | ||
1396 | idx_end = wbc->range_end >> PAGE_CACHE_SHIFT; | ||
1397 | if (idx_end > idx_start) { | ||
1398 | unsigned long l_npages = 1 + idx_end - idx_start; | ||
1399 | npages = l_npages; | ||
1400 | if (sizeof(npages) != sizeof(l_npages) && | ||
1401 | (unsigned long)npages != l_npages) | ||
1402 | npages = 0; | ||
1403 | } | ||
1404 | } | ||
1507 | how &= ~FLUSH_NOCOMMIT; | 1405 | how &= ~FLUSH_NOCOMMIT; |
1508 | spin_lock(&nfsi->req_lock); | 1406 | spin_lock(&nfsi->req_lock); |
1509 | do { | 1407 | do { |
1408 | wbc->pages_skipped = 0; | ||
1510 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); | 1409 | ret = nfs_wait_on_requests_locked(inode, idx_start, npages); |
1511 | if (ret != 0) | 1410 | if (ret != 0) |
1512 | continue; | 1411 | continue; |
1513 | pages = nfs_scan_dirty(inode, &head, idx_start, npages); | 1412 | pages = nfs_scan_dirty(mapping, wbc, &head); |
1514 | if (pages != 0) { | 1413 | if (pages != 0) { |
1515 | spin_unlock(&nfsi->req_lock); | 1414 | spin_unlock(&nfsi->req_lock); |
1516 | if (how & FLUSH_INVALIDATE) | 1415 | if (how & FLUSH_INVALIDATE) { |
1517 | nfs_cancel_dirty_list(&head); | 1416 | nfs_cancel_dirty_list(&head); |
1518 | else | 1417 | ret = pages; |
1418 | } else | ||
1519 | ret = nfs_flush_list(inode, &head, pages, how); | 1419 | ret = nfs_flush_list(inode, &head, pages, how); |
1520 | spin_lock(&nfsi->req_lock); | 1420 | spin_lock(&nfsi->req_lock); |
1521 | continue; | 1421 | continue; |
1522 | } | 1422 | } |
1423 | if (wbc->pages_skipped != 0) | ||
1424 | continue; | ||
1523 | if (nocommit) | 1425 | if (nocommit) |
1524 | break; | 1426 | break; |
1525 | pages = nfs_scan_commit(inode, &head, idx_start, npages); | 1427 | pages = nfs_scan_commit(inode, &head, idx_start, npages); |
1526 | if (pages == 0) | 1428 | if (pages == 0) { |
1429 | if (wbc->pages_skipped != 0) | ||
1430 | continue; | ||
1527 | break; | 1431 | break; |
1432 | } | ||
1528 | if (how & FLUSH_INVALIDATE) { | 1433 | if (how & FLUSH_INVALIDATE) { |
1529 | spin_unlock(&nfsi->req_lock); | 1434 | spin_unlock(&nfsi->req_lock); |
1530 | nfs_cancel_commit_list(&head); | 1435 | nfs_cancel_commit_list(&head); |
1436 | ret = pages; | ||
1531 | spin_lock(&nfsi->req_lock); | 1437 | spin_lock(&nfsi->req_lock); |
1532 | continue; | 1438 | continue; |
1533 | } | 1439 | } |
@@ -1540,6 +1446,106 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start, | |||
1540 | return ret; | 1446 | return ret; |
1541 | } | 1447 | } |
1542 | 1448 | ||
1449 | /* | ||
1450 | * flush the inode to disk. | ||
1451 | */ | ||
1452 | int nfs_wb_all(struct inode *inode) | ||
1453 | { | ||
1454 | struct address_space *mapping = inode->i_mapping; | ||
1455 | struct writeback_control wbc = { | ||
1456 | .bdi = mapping->backing_dev_info, | ||
1457 | .sync_mode = WB_SYNC_ALL, | ||
1458 | .nr_to_write = LONG_MAX, | ||
1459 | .for_writepages = 1, | ||
1460 | .range_cyclic = 1, | ||
1461 | }; | ||
1462 | int ret; | ||
1463 | |||
1464 | ret = generic_writepages(mapping, &wbc); | ||
1465 | if (ret < 0) | ||
1466 | goto out; | ||
1467 | ret = nfs_sync_mapping_wait(mapping, &wbc, 0); | ||
1468 | if (ret >= 0) | ||
1469 | return 0; | ||
1470 | out: | ||
1471 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | ||
1472 | return ret; | ||
1473 | } | ||
1474 | |||
1475 | int nfs_sync_mapping_range(struct address_space *mapping, loff_t range_start, loff_t range_end, int how) | ||
1476 | { | ||
1477 | struct writeback_control wbc = { | ||
1478 | .bdi = mapping->backing_dev_info, | ||
1479 | .sync_mode = WB_SYNC_ALL, | ||
1480 | .nr_to_write = LONG_MAX, | ||
1481 | .range_start = range_start, | ||
1482 | .range_end = range_end, | ||
1483 | .for_writepages = 1, | ||
1484 | }; | ||
1485 | int ret; | ||
1486 | |||
1487 | if (!(how & FLUSH_NOWRITEPAGE)) { | ||
1488 | ret = generic_writepages(mapping, &wbc); | ||
1489 | if (ret < 0) | ||
1490 | goto out; | ||
1491 | } | ||
1492 | ret = nfs_sync_mapping_wait(mapping, &wbc, how); | ||
1493 | if (ret >= 0) | ||
1494 | return 0; | ||
1495 | out: | ||
1496 | __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); | ||
1497 | return ret; | ||
1498 | } | ||
1499 | |||
1500 | int nfs_wb_page_priority(struct inode *inode, struct page *page, int how) | ||
1501 | { | ||
1502 | loff_t range_start = page_offset(page); | ||
1503 | loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1); | ||
1504 | struct writeback_control wbc = { | ||
1505 | .bdi = page->mapping->backing_dev_info, | ||
1506 | .sync_mode = WB_SYNC_ALL, | ||
1507 | .nr_to_write = LONG_MAX, | ||
1508 | .range_start = range_start, | ||
1509 | .range_end = range_end, | ||
1510 | }; | ||
1511 | int ret; | ||
1512 | |||
1513 | BUG_ON(!PageLocked(page)); | ||
1514 | if (!(how & FLUSH_NOWRITEPAGE) && clear_page_dirty_for_io(page)) { | ||
1515 | ret = nfs_writepage_locked(page, &wbc); | ||
1516 | if (ret < 0) | ||
1517 | goto out; | ||
1518 | } | ||
1519 | ret = nfs_sync_mapping_wait(page->mapping, &wbc, how); | ||
1520 | if (ret >= 0) | ||
1521 | return 0; | ||
1522 | out: | ||
1523 | __mark_inode_dirty(inode, I_DIRTY_PAGES); | ||
1524 | return ret; | ||
1525 | } | ||
1526 | |||
1527 | /* | ||
1528 | * Write back all requests on one page - we do this before reading it. | ||
1529 | */ | ||
1530 | int nfs_wb_page(struct inode *inode, struct page* page) | ||
1531 | { | ||
1532 | return nfs_wb_page_priority(inode, page, FLUSH_STABLE); | ||
1533 | } | ||
1534 | |||
1535 | int nfs_set_page_dirty(struct page *page) | ||
1536 | { | ||
1537 | struct nfs_page *req; | ||
1538 | |||
1539 | req = nfs_page_find_request(page); | ||
1540 | if (req != NULL) { | ||
1541 | /* Mark any existing write requests for flushing */ | ||
1542 | set_bit(PG_NEED_FLUSH, &req->wb_flags); | ||
1543 | nfs_release_request(req); | ||
1544 | } | ||
1545 | return __set_page_dirty_nobuffers(page); | ||
1546 | } | ||
1547 | |||
1548 | |||
1543 | int __init nfs_init_writepagecache(void) | 1549 | int __init nfs_init_writepagecache(void) |
1544 | { | 1550 | { |
1545 | nfs_wdata_cachep = kmem_cache_create("nfs_write_data", | 1551 | nfs_wdata_cachep = kmem_cache_create("nfs_write_data", |
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 64db601c2bd2..7f5bad0393b1 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c | |||
@@ -258,7 +258,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, | |||
258 | /* Now create the file and set attributes */ | 258 | /* Now create the file and set attributes */ |
259 | nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, | 259 | nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len, |
260 | attr, newfhp, | 260 | attr, newfhp, |
261 | argp->createmode, argp->verf, NULL); | 261 | argp->createmode, argp->verf, NULL, NULL); |
262 | 262 | ||
263 | RETURN_STATUS(nfserr); | 263 | RETURN_STATUS(nfserr); |
264 | } | 264 | } |
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index b4baca3053c3..277df40f098d 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -24,10 +24,6 @@ | |||
24 | 24 | ||
25 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 25 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
26 | 26 | ||
27 | #ifdef NFSD_OPTIMIZE_SPACE | ||
28 | # define inline | ||
29 | #endif | ||
30 | |||
31 | 27 | ||
32 | /* | 28 | /* |
33 | * Mapping of S_IF* types to NFS file types | 29 | * Mapping of S_IF* types to NFS file types |
@@ -42,14 +38,14 @@ static u32 nfs3_ftypes[] = { | |||
42 | /* | 38 | /* |
43 | * XDR functions for basic NFS types | 39 | * XDR functions for basic NFS types |
44 | */ | 40 | */ |
45 | static inline __be32 * | 41 | static __be32 * |
46 | encode_time3(__be32 *p, struct timespec *time) | 42 | encode_time3(__be32 *p, struct timespec *time) |
47 | { | 43 | { |
48 | *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); | 44 | *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec); |
49 | return p; | 45 | return p; |
50 | } | 46 | } |
51 | 47 | ||
52 | static inline __be32 * | 48 | static __be32 * |
53 | decode_time3(__be32 *p, struct timespec *time) | 49 | decode_time3(__be32 *p, struct timespec *time) |
54 | { | 50 | { |
55 | time->tv_sec = ntohl(*p++); | 51 | time->tv_sec = ntohl(*p++); |
@@ -57,7 +53,7 @@ decode_time3(__be32 *p, struct timespec *time) | |||
57 | return p; | 53 | return p; |
58 | } | 54 | } |
59 | 55 | ||
60 | static inline __be32 * | 56 | static __be32 * |
61 | decode_fh(__be32 *p, struct svc_fh *fhp) | 57 | decode_fh(__be32 *p, struct svc_fh *fhp) |
62 | { | 58 | { |
63 | unsigned int size; | 59 | unsigned int size; |
@@ -77,7 +73,7 @@ __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp) | |||
77 | return decode_fh(p, fhp); | 73 | return decode_fh(p, fhp); |
78 | } | 74 | } |
79 | 75 | ||
80 | static inline __be32 * | 76 | static __be32 * |
81 | encode_fh(__be32 *p, struct svc_fh *fhp) | 77 | encode_fh(__be32 *p, struct svc_fh *fhp) |
82 | { | 78 | { |
83 | unsigned int size = fhp->fh_handle.fh_size; | 79 | unsigned int size = fhp->fh_handle.fh_size; |
@@ -91,7 +87,7 @@ encode_fh(__be32 *p, struct svc_fh *fhp) | |||
91 | * Decode a file name and make sure that the path contains | 87 | * Decode a file name and make sure that the path contains |
92 | * no slashes or null bytes. | 88 | * no slashes or null bytes. |
93 | */ | 89 | */ |
94 | static inline __be32 * | 90 | static __be32 * |
95 | decode_filename(__be32 *p, char **namp, int *lenp) | 91 | decode_filename(__be32 *p, char **namp, int *lenp) |
96 | { | 92 | { |
97 | char *name; | 93 | char *name; |
@@ -107,7 +103,7 @@ decode_filename(__be32 *p, char **namp, int *lenp) | |||
107 | return p; | 103 | return p; |
108 | } | 104 | } |
109 | 105 | ||
110 | static inline __be32 * | 106 | static __be32 * |
111 | decode_sattr3(__be32 *p, struct iattr *iap) | 107 | decode_sattr3(__be32 *p, struct iattr *iap) |
112 | { | 108 | { |
113 | u32 tmp; | 109 | u32 tmp; |
@@ -153,7 +149,7 @@ decode_sattr3(__be32 *p, struct iattr *iap) | |||
153 | return p; | 149 | return p; |
154 | } | 150 | } |
155 | 151 | ||
156 | static inline __be32 * | 152 | static __be32 * |
157 | encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, | 153 | encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, |
158 | struct kstat *stat) | 154 | struct kstat *stat) |
159 | { | 155 | { |
@@ -186,7 +182,7 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, | |||
186 | return p; | 182 | return p; |
187 | } | 183 | } |
188 | 184 | ||
189 | static inline __be32 * | 185 | static __be32 * |
190 | encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) | 186 | encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp) |
191 | { | 187 | { |
192 | struct inode *inode = fhp->fh_dentry->d_inode; | 188 | struct inode *inode = fhp->fh_dentry->d_inode; |
@@ -776,7 +772,7 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, | |||
776 | return xdr_ressize_check(rqstp, p); | 772 | return xdr_ressize_check(rqstp, p); |
777 | } | 773 | } |
778 | 774 | ||
779 | static inline __be32 * | 775 | static __be32 * |
780 | encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, | 776 | encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, |
781 | int namlen, ino_t ino) | 777 | int namlen, ino_t ino) |
782 | { | 778 | { |
@@ -790,7 +786,7 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, | |||
790 | return p; | 786 | return p; |
791 | } | 787 | } |
792 | 788 | ||
793 | static inline __be32 * | 789 | static __be32 * |
794 | encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, | 790 | encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, |
795 | struct svc_fh *fhp) | 791 | struct svc_fh *fhp) |
796 | { | 792 | { |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 0a7bbdc4a10a..50bc94243ca1 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -93,6 +93,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o | |||
93 | { | 93 | { |
94 | struct svc_fh resfh; | 94 | struct svc_fh resfh; |
95 | __be32 status; | 95 | __be32 status; |
96 | int created = 0; | ||
96 | 97 | ||
97 | fh_init(&resfh, NFS4_FHSIZE); | 98 | fh_init(&resfh, NFS4_FHSIZE); |
98 | open->op_truncate = 0; | 99 | open->op_truncate = 0; |
@@ -105,28 +106,27 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o | |||
105 | status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, | 106 | status = nfsd_create_v3(rqstp, current_fh, open->op_fname.data, |
106 | open->op_fname.len, &open->op_iattr, | 107 | open->op_fname.len, &open->op_iattr, |
107 | &resfh, open->op_createmode, | 108 | &resfh, open->op_createmode, |
108 | (u32 *)open->op_verf.data, &open->op_truncate); | 109 | (u32 *)open->op_verf.data, &open->op_truncate, &created); |
109 | } | 110 | } else { |
110 | else { | ||
111 | status = nfsd_lookup(rqstp, current_fh, | 111 | status = nfsd_lookup(rqstp, current_fh, |
112 | open->op_fname.data, open->op_fname.len, &resfh); | 112 | open->op_fname.data, open->op_fname.len, &resfh); |
113 | fh_unlock(current_fh); | 113 | fh_unlock(current_fh); |
114 | } | 114 | } |
115 | if (status) | ||
116 | goto out; | ||
115 | 117 | ||
116 | if (!status) { | 118 | set_change_info(&open->op_cinfo, current_fh); |
117 | set_change_info(&open->op_cinfo, current_fh); | ||
118 | 119 | ||
119 | /* set reply cache */ | 120 | /* set reply cache */ |
120 | fh_dup2(current_fh, &resfh); | 121 | fh_dup2(current_fh, &resfh); |
121 | open->op_stateowner->so_replay.rp_openfh_len = | 122 | open->op_stateowner->so_replay.rp_openfh_len = resfh.fh_handle.fh_size; |
122 | resfh.fh_handle.fh_size; | 123 | memcpy(open->op_stateowner->so_replay.rp_openfh, |
123 | memcpy(open->op_stateowner->so_replay.rp_openfh, | 124 | &resfh.fh_handle.fh_base, resfh.fh_handle.fh_size); |
124 | &resfh.fh_handle.fh_base, | ||
125 | resfh.fh_handle.fh_size); | ||
126 | 125 | ||
126 | if (!created) | ||
127 | status = do_open_permission(rqstp, current_fh, open, MAY_NOP); | 127 | status = do_open_permission(rqstp, current_fh, open, MAY_NOP); |
128 | } | ||
129 | 128 | ||
129 | out: | ||
130 | fh_put(&resfh); | 130 | fh_put(&resfh); |
131 | return status; | 131 | return status; |
132 | } | 132 | } |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 293b6495829f..640c92b2a9f7 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -84,10 +84,10 @@ static void nfs4_set_recdir(char *recdir); | |||
84 | */ | 84 | */ |
85 | static DEFINE_MUTEX(client_mutex); | 85 | static DEFINE_MUTEX(client_mutex); |
86 | 86 | ||
87 | static kmem_cache_t *stateowner_slab = NULL; | 87 | static struct kmem_cache *stateowner_slab = NULL; |
88 | static kmem_cache_t *file_slab = NULL; | 88 | static struct kmem_cache *file_slab = NULL; |
89 | static kmem_cache_t *stateid_slab = NULL; | 89 | static struct kmem_cache *stateid_slab = NULL; |
90 | static kmem_cache_t *deleg_slab = NULL; | 90 | static struct kmem_cache *deleg_slab = NULL; |
91 | 91 | ||
92 | void | 92 | void |
93 | nfs4_lock_state(void) | 93 | nfs4_lock_state(void) |
@@ -1003,7 +1003,7 @@ alloc_init_file(struct inode *ino) | |||
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | static void | 1005 | static void |
1006 | nfsd4_free_slab(kmem_cache_t **slab) | 1006 | nfsd4_free_slab(struct kmem_cache **slab) |
1007 | { | 1007 | { |
1008 | if (*slab == NULL) | 1008 | if (*slab == NULL) |
1009 | return; | 1009 | return; |
@@ -1829,9 +1829,8 @@ out: | |||
1829 | } | 1829 | } |
1830 | 1830 | ||
1831 | static struct workqueue_struct *laundry_wq; | 1831 | static struct workqueue_struct *laundry_wq; |
1832 | static struct work_struct laundromat_work; | 1832 | static void laundromat_main(struct work_struct *); |
1833 | static void laundromat_main(void *); | 1833 | static DECLARE_DELAYED_WORK(laundromat_work, laundromat_main); |
1834 | static DECLARE_WORK(laundromat_work, laundromat_main, NULL); | ||
1835 | 1834 | ||
1836 | __be32 | 1835 | __be32 |
1837 | nfsd4_renew(clientid_t *clid) | 1836 | nfsd4_renew(clientid_t *clid) |
@@ -1940,7 +1939,7 @@ nfs4_laundromat(void) | |||
1940 | } | 1939 | } |
1941 | 1940 | ||
1942 | void | 1941 | void |
1943 | laundromat_main(void *not_used) | 1942 | laundromat_main(struct work_struct *not_used) |
1944 | { | 1943 | { |
1945 | time_t t; | 1944 | time_t t; |
1946 | 1945 | ||
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 56ebb1443e0e..f5243f943996 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -18,11 +18,6 @@ | |||
18 | 18 | ||
19 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 19 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
20 | 20 | ||
21 | |||
22 | #ifdef NFSD_OPTIMIZE_SPACE | ||
23 | # define inline | ||
24 | #endif | ||
25 | |||
26 | /* | 21 | /* |
27 | * Mapping of S_IF* types to NFS file types | 22 | * Mapping of S_IF* types to NFS file types |
28 | */ | 23 | */ |
@@ -55,7 +50,7 @@ __be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp) | |||
55 | return decode_fh(p, fhp); | 50 | return decode_fh(p, fhp); |
56 | } | 51 | } |
57 | 52 | ||
58 | static inline __be32 * | 53 | static __be32 * |
59 | encode_fh(__be32 *p, struct svc_fh *fhp) | 54 | encode_fh(__be32 *p, struct svc_fh *fhp) |
60 | { | 55 | { |
61 | memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); | 56 | memcpy(p, &fhp->fh_handle.fh_base, NFS_FHSIZE); |
@@ -66,7 +61,7 @@ encode_fh(__be32 *p, struct svc_fh *fhp) | |||
66 | * Decode a file name and make sure that the path contains | 61 | * Decode a file name and make sure that the path contains |
67 | * no slashes or null bytes. | 62 | * no slashes or null bytes. |
68 | */ | 63 | */ |
69 | static inline __be32 * | 64 | static __be32 * |
70 | decode_filename(__be32 *p, char **namp, int *lenp) | 65 | decode_filename(__be32 *p, char **namp, int *lenp) |
71 | { | 66 | { |
72 | char *name; | 67 | char *name; |
@@ -82,7 +77,7 @@ decode_filename(__be32 *p, char **namp, int *lenp) | |||
82 | return p; | 77 | return p; |
83 | } | 78 | } |
84 | 79 | ||
85 | static inline __be32 * | 80 | static __be32 * |
86 | decode_pathname(__be32 *p, char **namp, int *lenp) | 81 | decode_pathname(__be32 *p, char **namp, int *lenp) |
87 | { | 82 | { |
88 | char *name; | 83 | char *name; |
@@ -98,7 +93,7 @@ decode_pathname(__be32 *p, char **namp, int *lenp) | |||
98 | return p; | 93 | return p; |
99 | } | 94 | } |
100 | 95 | ||
101 | static inline __be32 * | 96 | static __be32 * |
102 | decode_sattr(__be32 *p, struct iattr *iap) | 97 | decode_sattr(__be32 *p, struct iattr *iap) |
103 | { | 98 | { |
104 | u32 tmp, tmp1; | 99 | u32 tmp, tmp1; |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index f21e917bb8ed..bb4d926e4487 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1177,7 +1177,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1177 | /* | 1177 | /* |
1178 | * Get the dir op function pointer. | 1178 | * Get the dir op function pointer. |
1179 | */ | 1179 | */ |
1180 | err = nfserr_perm; | 1180 | err = 0; |
1181 | switch (type) { | 1181 | switch (type) { |
1182 | case S_IFREG: | 1182 | case S_IFREG: |
1183 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); | 1183 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); |
@@ -1237,7 +1237,7 @@ __be32 | |||
1237 | nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | 1237 | nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, |
1238 | char *fname, int flen, struct iattr *iap, | 1238 | char *fname, int flen, struct iattr *iap, |
1239 | struct svc_fh *resfhp, int createmode, u32 *verifier, | 1239 | struct svc_fh *resfhp, int createmode, u32 *verifier, |
1240 | int *truncp) | 1240 | int *truncp, int *created) |
1241 | { | 1241 | { |
1242 | struct dentry *dentry, *dchild = NULL; | 1242 | struct dentry *dentry, *dchild = NULL; |
1243 | struct inode *dirp; | 1243 | struct inode *dirp; |
@@ -1331,6 +1331,8 @@ nfsd_create_v3(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
1331 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); | 1331 | host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL); |
1332 | if (host_err < 0) | 1332 | if (host_err < 0) |
1333 | goto out_nfserr; | 1333 | goto out_nfserr; |
1334 | if (created) | ||
1335 | *created = 1; | ||
1334 | 1336 | ||
1335 | if (EX_ISSYNC(fhp->fh_export)) { | 1337 | if (EX_ISSYNC(fhp->fh_export)) { |
1336 | err = nfserrno(nfsd_sync_dir(dentry)); | 1338 | err = nfserrno(nfsd_sync_dir(dentry)); |
diff --git a/fs/nls/nls_cp936.c b/fs/nls/nls_cp936.c index 046fde8170ea..65e640c61c8b 100644 --- a/fs/nls/nls_cp936.c +++ b/fs/nls/nls_cp936.c | |||
@@ -4421,6 +4421,73 @@ static wchar_t *page_charset2uni[256] = { | |||
4421 | c2u_F8, c2u_F9, c2u_FA, c2u_FB, c2u_FC, c2u_FD, c2u_FE, NULL, | 4421 | c2u_F8, c2u_F9, c2u_FA, c2u_FB, c2u_FC, c2u_FD, c2u_FE, NULL, |
4422 | }; | 4422 | }; |
4423 | 4423 | ||
4424 | static unsigned char u2c_00[512] = { | ||
4425 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */ | ||
4426 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */ | ||
4427 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0B */ | ||
4428 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0C-0x0F */ | ||
4429 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x13 */ | ||
4430 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x14-0x17 */ | ||
4431 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1B */ | ||
4432 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1C-0x1F */ | ||
4433 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x23 */ | ||
4434 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x24-0x27 */ | ||
4435 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2B */ | ||
4436 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2C-0x2F */ | ||
4437 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x33 */ | ||
4438 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x34-0x37 */ | ||
4439 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3B */ | ||
4440 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3C-0x3F */ | ||
4441 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x43 */ | ||
4442 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x44-0x47 */ | ||
4443 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4B */ | ||
4444 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4C-0x4F */ | ||
4445 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x53 */ | ||
4446 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x54-0x57 */ | ||
4447 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5B */ | ||
4448 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5C-0x5F */ | ||
4449 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x63 */ | ||
4450 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x64-0x67 */ | ||
4451 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6B */ | ||
4452 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6C-0x6F */ | ||
4453 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x73 */ | ||
4454 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x74-0x77 */ | ||
4455 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7B */ | ||
4456 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7C-0x7F */ | ||
4457 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x83 */ | ||
4458 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x84-0x87 */ | ||
4459 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8B */ | ||
4460 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8C-0x8F */ | ||
4461 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x93 */ | ||
4462 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x94-0x97 */ | ||
4463 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9B */ | ||
4464 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9C-0x9F */ | ||
4465 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA0-0xA3 */ | ||
4466 | 0xA1, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xEC, /* 0xA4-0xA7 */ | ||
4467 | 0xA1, 0xA7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xA8-0xAB */ | ||
4468 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xAC-0xAF */ | ||
4469 | 0xA1, 0xE3, 0xA1, 0xC0, 0x00, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */ | ||
4470 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xA4, /* 0xB4-0xB7 */ | ||
4471 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB8-0xBB */ | ||
4472 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xBC-0xBF */ | ||
4473 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC0-0xC3 */ | ||
4474 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC4-0xC7 */ | ||
4475 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xC8-0xCB */ | ||
4476 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xCC-0xCF */ | ||
4477 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD0-0xD3 */ | ||
4478 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xC1, /* 0xD4-0xD7 */ | ||
4479 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD8-0xDB */ | ||
4480 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xDC-0xDF */ | ||
4481 | 0xA8, 0xA4, 0xA8, 0xA2, 0x00, 0x00, 0x00, 0x00, /* 0xE0-0xE3 */ | ||
4482 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xE4-0xE7 */ | ||
4483 | 0xA8, 0xA8, 0xA8, 0xA6, 0xA8, 0xBA, 0x00, 0x00, /* 0xE8-0xEB */ | ||
4484 | 0xA8, 0xAC, 0xA8, 0xAA, 0x00, 0x00, 0x00, 0x00, /* 0xEC-0xEF */ | ||
4485 | 0x00, 0x00, 0x00, 0x00, 0xA8, 0xB0, 0xA8, 0xAE, /* 0xF0-0xF3 */ | ||
4486 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xC2, /* 0xF4-0xF7 */ | ||
4487 | 0x00, 0x00, 0xA8, 0xB4, 0xA8, 0xB2, 0x00, 0x00, /* 0xF8-0xFB */ | ||
4488 | 0xA8, 0xB9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xFC-0xFF */ | ||
4489 | }; | ||
4490 | |||
4424 | static unsigned char u2c_01[512] = { | 4491 | static unsigned char u2c_01[512] = { |
4425 | 0xA8, 0xA1, 0xA8, 0xA1, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */ | 4492 | 0xA8, 0xA1, 0xA8, 0xA1, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x03 */ |
4426 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */ | 4493 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x04-0x07 */ |
@@ -10825,7 +10892,7 @@ static unsigned char u2c_FF[512] = { | |||
10825 | }; | 10892 | }; |
10826 | 10893 | ||
10827 | static unsigned char *page_uni2charset[256] = { | 10894 | static unsigned char *page_uni2charset[256] = { |
10828 | NULL, u2c_01, u2c_02, u2c_03, u2c_04, NULL, NULL, NULL, | 10895 | u2c_00, u2c_01, u2c_02, u2c_03, u2c_04, NULL, NULL, NULL, |
10829 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 10896 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
10830 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 10897 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
10831 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 10898 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
@@ -10936,11 +11003,34 @@ static int uni2char(const wchar_t uni, | |||
10936 | unsigned char *uni2charset; | 11003 | unsigned char *uni2charset; |
10937 | unsigned char cl = uni&0xFF; | 11004 | unsigned char cl = uni&0xFF; |
10938 | unsigned char ch = (uni>>8)&0xFF; | 11005 | unsigned char ch = (uni>>8)&0xFF; |
10939 | int n; | 11006 | unsigned char out0,out1; |
10940 | 11007 | ||
10941 | if (boundlen <= 0) | 11008 | if (boundlen <= 0) |
10942 | return -ENAMETOOLONG; | 11009 | return -ENAMETOOLONG; |
10943 | 11010 | ||
11011 | if (uni == 0x20ac) {/* Euro symbol.The only exception with a non-ascii unicode */ | ||
11012 | out[0] = 0x80; | ||
11013 | return 1; | ||
11014 | } | ||
11015 | |||
11016 | if (ch == 0) { /* handle the U00 plane*/ | ||
11017 | /* if (cl == 0) return -EINVAL;*/ /*U0000 is legal in cp936*/ | ||
11018 | out0 = u2c_00[cl*2]; | ||
11019 | out1 = u2c_00[cl*2+1]; | ||
11020 | if (out0 == 0x00 && out1 == 0x00) { | ||
11021 | if (cl<0x80) { | ||
11022 | out[0] = cl; | ||
11023 | return 1; | ||
11024 | } | ||
11025 | return -EINVAL; | ||
11026 | } else { | ||
11027 | if (boundlen <= 1) | ||
11028 | return -ENAMETOOLONG; | ||
11029 | out[0] = out0; | ||
11030 | out[1] = out1; | ||
11031 | return 2; | ||
11032 | } | ||
11033 | } | ||
10944 | 11034 | ||
10945 | uni2charset = page_uni2charset[ch]; | 11035 | uni2charset = page_uni2charset[ch]; |
10946 | if (uni2charset) { | 11036 | if (uni2charset) { |
@@ -10950,15 +11040,10 @@ static int uni2char(const wchar_t uni, | |||
10950 | out[1] = uni2charset[cl*2+1]; | 11040 | out[1] = uni2charset[cl*2+1]; |
10951 | if (out[0] == 0x00 && out[1] == 0x00) | 11041 | if (out[0] == 0x00 && out[1] == 0x00) |
10952 | return -EINVAL; | 11042 | return -EINVAL; |
10953 | n = 2; | 11043 | return 2; |
10954 | } else if (ch==0 && cl) { | ||
10955 | out[0] = cl; | ||
10956 | n = 1; | ||
10957 | } | 11044 | } |
10958 | else | 11045 | else |
10959 | return -EINVAL; | 11046 | return -EINVAL; |
10960 | |||
10961 | return n; | ||
10962 | } | 11047 | } |
10963 | 11048 | ||
10964 | static int char2uni(const unsigned char *rawstring, int boundlen, | 11049 | static int char2uni(const unsigned char *rawstring, int boundlen, |
@@ -10972,7 +11057,11 @@ static int char2uni(const unsigned char *rawstring, int boundlen, | |||
10972 | return -ENAMETOOLONG; | 11057 | return -ENAMETOOLONG; |
10973 | 11058 | ||
10974 | if (boundlen == 1) { | 11059 | if (boundlen == 1) { |
10975 | *uni = rawstring[0]; | 11060 | if (rawstring[0]==0x80) { /* Euro symbol.The only exception with a non-ascii unicode */ |
11061 | *uni = 0x20ac; | ||
11062 | } else { | ||
11063 | *uni = rawstring[0]; | ||
11064 | } | ||
10976 | return 1; | 11065 | return 1; |
10977 | } | 11066 | } |
10978 | 11067 | ||
@@ -10986,7 +11075,11 @@ static int char2uni(const unsigned char *rawstring, int boundlen, | |||
10986 | return -EINVAL; | 11075 | return -EINVAL; |
10987 | n = 2; | 11076 | n = 2; |
10988 | } else{ | 11077 | } else{ |
10989 | *uni = ch; | 11078 | if (ch==0x80) {/* Euro symbol.The only exception with a non-ascii unicode */ |
11079 | *uni = 0x20ac; | ||
11080 | } else { | ||
11081 | *uni = ch; | ||
11082 | } | ||
10990 | n = 1; | 11083 | n = 1; |
10991 | } | 11084 | } |
10992 | return n; | 11085 | return n; |
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 9f08e851cfb6..c577d8e1bd95 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c | |||
@@ -1272,7 +1272,7 @@ ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec) | |||
1272 | { | 1272 | { |
1273 | ntfs_attr_search_ctx *ctx; | 1273 | ntfs_attr_search_ctx *ctx; |
1274 | 1274 | ||
1275 | ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, SLAB_NOFS); | 1275 | ctx = kmem_cache_alloc(ntfs_attr_ctx_cache, GFP_NOFS); |
1276 | if (ctx) | 1276 | if (ctx) |
1277 | ntfs_attr_init_search_ctx(ctx, ni, mrec); | 1277 | ntfs_attr_init_search_ctx(ctx, ni, mrec); |
1278 | return ctx; | 1278 | return ctx; |
diff --git a/fs/ntfs/index.c b/fs/ntfs/index.c index e32cde486362..2194eff49743 100644 --- a/fs/ntfs/index.c +++ b/fs/ntfs/index.c | |||
@@ -38,7 +38,7 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni) | |||
38 | { | 38 | { |
39 | ntfs_index_context *ictx; | 39 | ntfs_index_context *ictx; |
40 | 40 | ||
41 | ictx = kmem_cache_alloc(ntfs_index_ctx_cache, SLAB_NOFS); | 41 | ictx = kmem_cache_alloc(ntfs_index_ctx_cache, GFP_NOFS); |
42 | if (ictx) | 42 | if (ictx) |
43 | *ictx = (ntfs_index_context){ .idx_ni = idx_ni }; | 43 | *ictx = (ntfs_index_context){ .idx_ni = idx_ni }; |
44 | return ictx; | 44 | return ictx; |
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 2d3de9c89818..247989891b4b 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -324,7 +324,7 @@ struct inode *ntfs_alloc_big_inode(struct super_block *sb) | |||
324 | ntfs_inode *ni; | 324 | ntfs_inode *ni; |
325 | 325 | ||
326 | ntfs_debug("Entering."); | 326 | ntfs_debug("Entering."); |
327 | ni = kmem_cache_alloc(ntfs_big_inode_cache, SLAB_NOFS); | 327 | ni = kmem_cache_alloc(ntfs_big_inode_cache, GFP_NOFS); |
328 | if (likely(ni != NULL)) { | 328 | if (likely(ni != NULL)) { |
329 | ni->state = 0; | 329 | ni->state = 0; |
330 | return VFS_I(ni); | 330 | return VFS_I(ni); |
@@ -349,7 +349,7 @@ static inline ntfs_inode *ntfs_alloc_extent_inode(void) | |||
349 | ntfs_inode *ni; | 349 | ntfs_inode *ni; |
350 | 350 | ||
351 | ntfs_debug("Entering."); | 351 | ntfs_debug("Entering."); |
352 | ni = kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS); | 352 | ni = kmem_cache_alloc(ntfs_inode_cache, GFP_NOFS); |
353 | if (likely(ni != NULL)) { | 353 | if (likely(ni != NULL)) { |
354 | ni->state = 0; | 354 | ni->state = 0; |
355 | return ni; | 355 | return ni; |
diff --git a/fs/ntfs/unistr.c b/fs/ntfs/unistr.c index 6a495f7369f9..005ca4b0f132 100644 --- a/fs/ntfs/unistr.c +++ b/fs/ntfs/unistr.c | |||
@@ -266,7 +266,7 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins, | |||
266 | 266 | ||
267 | /* We do not trust outside sources. */ | 267 | /* We do not trust outside sources. */ |
268 | if (likely(ins)) { | 268 | if (likely(ins)) { |
269 | ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); | 269 | ucs = kmem_cache_alloc(ntfs_name_cache, GFP_NOFS); |
270 | if (likely(ucs)) { | 270 | if (likely(ucs)) { |
271 | for (i = o = 0; i < ins_len; i += wc_len) { | 271 | for (i = o = 0; i < ins_len; i += wc_len) { |
272 | wc_len = nls->char2uni(ins + i, ins_len - i, | 272 | wc_len = nls->char2uni(ins + i, ins_len - i, |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index f43bc5f18a35..edc91ca3792a 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -52,14 +52,14 @@ static int ocfs2_extent_contig(struct inode *inode, | |||
52 | u64 blkno); | 52 | u64 blkno); |
53 | 53 | ||
54 | static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, | 54 | static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, |
55 | struct ocfs2_journal_handle *handle, | 55 | handle_t *handle, |
56 | struct inode *inode, | 56 | struct inode *inode, |
57 | int wanted, | 57 | int wanted, |
58 | struct ocfs2_alloc_context *meta_ac, | 58 | struct ocfs2_alloc_context *meta_ac, |
59 | struct buffer_head *bhs[]); | 59 | struct buffer_head *bhs[]); |
60 | 60 | ||
61 | static int ocfs2_add_branch(struct ocfs2_super *osb, | 61 | static int ocfs2_add_branch(struct ocfs2_super *osb, |
62 | struct ocfs2_journal_handle *handle, | 62 | handle_t *handle, |
63 | struct inode *inode, | 63 | struct inode *inode, |
64 | struct buffer_head *fe_bh, | 64 | struct buffer_head *fe_bh, |
65 | struct buffer_head *eb_bh, | 65 | struct buffer_head *eb_bh, |
@@ -67,14 +67,14 @@ static int ocfs2_add_branch(struct ocfs2_super *osb, | |||
67 | struct ocfs2_alloc_context *meta_ac); | 67 | struct ocfs2_alloc_context *meta_ac); |
68 | 68 | ||
69 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | 69 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, |
70 | struct ocfs2_journal_handle *handle, | 70 | handle_t *handle, |
71 | struct inode *inode, | 71 | struct inode *inode, |
72 | struct buffer_head *fe_bh, | 72 | struct buffer_head *fe_bh, |
73 | struct ocfs2_alloc_context *meta_ac, | 73 | struct ocfs2_alloc_context *meta_ac, |
74 | struct buffer_head **ret_new_eb_bh); | 74 | struct buffer_head **ret_new_eb_bh); |
75 | 75 | ||
76 | static int ocfs2_do_insert_extent(struct ocfs2_super *osb, | 76 | static int ocfs2_do_insert_extent(struct ocfs2_super *osb, |
77 | struct ocfs2_journal_handle *handle, | 77 | handle_t *handle, |
78 | struct inode *inode, | 78 | struct inode *inode, |
79 | struct buffer_head *fe_bh, | 79 | struct buffer_head *fe_bh, |
80 | u64 blkno, | 80 | u64 blkno, |
@@ -152,7 +152,7 @@ bail: | |||
152 | * l_count for you | 152 | * l_count for you |
153 | */ | 153 | */ |
154 | static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, | 154 | static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, |
155 | struct ocfs2_journal_handle *handle, | 155 | handle_t *handle, |
156 | struct inode *inode, | 156 | struct inode *inode, |
157 | int wanted, | 157 | int wanted, |
158 | struct ocfs2_alloc_context *meta_ac, | 158 | struct ocfs2_alloc_context *meta_ac, |
@@ -253,7 +253,7 @@ bail: | |||
253 | * contain a single record with e_clusters == 0. | 253 | * contain a single record with e_clusters == 0. |
254 | */ | 254 | */ |
255 | static int ocfs2_add_branch(struct ocfs2_super *osb, | 255 | static int ocfs2_add_branch(struct ocfs2_super *osb, |
256 | struct ocfs2_journal_handle *handle, | 256 | handle_t *handle, |
257 | struct inode *inode, | 257 | struct inode *inode, |
258 | struct buffer_head *fe_bh, | 258 | struct buffer_head *fe_bh, |
259 | struct buffer_head *eb_bh, | 259 | struct buffer_head *eb_bh, |
@@ -418,7 +418,7 @@ bail: | |||
418 | * after this call. | 418 | * after this call. |
419 | */ | 419 | */ |
420 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, | 420 | static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, |
421 | struct ocfs2_journal_handle *handle, | 421 | handle_t *handle, |
422 | struct inode *inode, | 422 | struct inode *inode, |
423 | struct buffer_head *fe_bh, | 423 | struct buffer_head *fe_bh, |
424 | struct ocfs2_alloc_context *meta_ac, | 424 | struct ocfs2_alloc_context *meta_ac, |
@@ -520,7 +520,7 @@ bail: | |||
520 | * down. | 520 | * down. |
521 | */ | 521 | */ |
522 | static int ocfs2_do_insert_extent(struct ocfs2_super *osb, | 522 | static int ocfs2_do_insert_extent(struct ocfs2_super *osb, |
523 | struct ocfs2_journal_handle *handle, | 523 | handle_t *handle, |
524 | struct inode *inode, | 524 | struct inode *inode, |
525 | struct buffer_head *fe_bh, | 525 | struct buffer_head *fe_bh, |
526 | u64 start_blk, | 526 | u64 start_blk, |
@@ -809,7 +809,7 @@ bail: | |||
809 | 809 | ||
810 | /* the caller needs to update fe->i_clusters */ | 810 | /* the caller needs to update fe->i_clusters */ |
811 | int ocfs2_insert_extent(struct ocfs2_super *osb, | 811 | int ocfs2_insert_extent(struct ocfs2_super *osb, |
812 | struct ocfs2_journal_handle *handle, | 812 | handle_t *handle, |
813 | struct inode *inode, | 813 | struct inode *inode, |
814 | struct buffer_head *fe_bh, | 814 | struct buffer_head *fe_bh, |
815 | u64 start_blk, | 815 | u64 start_blk, |
@@ -951,7 +951,7 @@ static int ocfs2_truncate_log_can_coalesce(struct ocfs2_truncate_log *tl, | |||
951 | } | 951 | } |
952 | 952 | ||
953 | static int ocfs2_truncate_log_append(struct ocfs2_super *osb, | 953 | static int ocfs2_truncate_log_append(struct ocfs2_super *osb, |
954 | struct ocfs2_journal_handle *handle, | 954 | handle_t *handle, |
955 | u64 start_blk, | 955 | u64 start_blk, |
956 | unsigned int num_clusters) | 956 | unsigned int num_clusters) |
957 | { | 957 | { |
@@ -1034,7 +1034,7 @@ bail: | |||
1034 | } | 1034 | } |
1035 | 1035 | ||
1036 | static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, | 1036 | static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, |
1037 | struct ocfs2_journal_handle *handle, | 1037 | handle_t *handle, |
1038 | struct inode *data_alloc_inode, | 1038 | struct inode *data_alloc_inode, |
1039 | struct buffer_head *data_alloc_bh) | 1039 | struct buffer_head *data_alloc_bh) |
1040 | { | 1040 | { |
@@ -1113,7 +1113,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1113 | { | 1113 | { |
1114 | int status; | 1114 | int status; |
1115 | unsigned int num_to_flush; | 1115 | unsigned int num_to_flush; |
1116 | struct ocfs2_journal_handle *handle = NULL; | 1116 | handle_t *handle; |
1117 | struct inode *tl_inode = osb->osb_tl_inode; | 1117 | struct inode *tl_inode = osb->osb_tl_inode; |
1118 | struct inode *data_alloc_inode = NULL; | 1118 | struct inode *data_alloc_inode = NULL; |
1119 | struct buffer_head *tl_bh = osb->osb_tl_bh; | 1119 | struct buffer_head *tl_bh = osb->osb_tl_bh; |
@@ -1130,7 +1130,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1130 | if (!OCFS2_IS_VALID_DINODE(di)) { | 1130 | if (!OCFS2_IS_VALID_DINODE(di)) { |
1131 | OCFS2_RO_ON_INVALID_DINODE(osb->sb, di); | 1131 | OCFS2_RO_ON_INVALID_DINODE(osb->sb, di); |
1132 | status = -EIO; | 1132 | status = -EIO; |
1133 | goto bail; | 1133 | goto out; |
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | num_to_flush = le16_to_cpu(tl->tl_used); | 1136 | num_to_flush = le16_to_cpu(tl->tl_used); |
@@ -1138,14 +1138,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1138 | num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno); | 1138 | num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno); |
1139 | if (!num_to_flush) { | 1139 | if (!num_to_flush) { |
1140 | status = 0; | 1140 | status = 0; |
1141 | goto bail; | 1141 | goto out; |
1142 | } | ||
1143 | |||
1144 | handle = ocfs2_alloc_handle(osb); | ||
1145 | if (!handle) { | ||
1146 | status = -ENOMEM; | ||
1147 | mlog_errno(status); | ||
1148 | goto bail; | ||
1149 | } | 1142 | } |
1150 | 1143 | ||
1151 | data_alloc_inode = ocfs2_get_system_file_inode(osb, | 1144 | data_alloc_inode = ocfs2_get_system_file_inode(osb, |
@@ -1154,41 +1147,40 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1154 | if (!data_alloc_inode) { | 1147 | if (!data_alloc_inode) { |
1155 | status = -EINVAL; | 1148 | status = -EINVAL; |
1156 | mlog(ML_ERROR, "Could not get bitmap inode!\n"); | 1149 | mlog(ML_ERROR, "Could not get bitmap inode!\n"); |
1157 | goto bail; | 1150 | goto out; |
1158 | } | 1151 | } |
1159 | 1152 | ||
1160 | ocfs2_handle_add_inode(handle, data_alloc_inode); | 1153 | mutex_lock(&data_alloc_inode->i_mutex); |
1161 | status = ocfs2_meta_lock(data_alloc_inode, handle, &data_alloc_bh, 1); | 1154 | |
1155 | status = ocfs2_meta_lock(data_alloc_inode, &data_alloc_bh, 1); | ||
1162 | if (status < 0) { | 1156 | if (status < 0) { |
1163 | mlog_errno(status); | 1157 | mlog_errno(status); |
1164 | goto bail; | 1158 | goto out_mutex; |
1165 | } | 1159 | } |
1166 | 1160 | ||
1167 | handle = ocfs2_start_trans(osb, handle, OCFS2_TRUNCATE_LOG_UPDATE); | 1161 | handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_UPDATE); |
1168 | if (IS_ERR(handle)) { | 1162 | if (IS_ERR(handle)) { |
1169 | status = PTR_ERR(handle); | 1163 | status = PTR_ERR(handle); |
1170 | handle = NULL; | ||
1171 | mlog_errno(status); | 1164 | mlog_errno(status); |
1172 | goto bail; | 1165 | goto out_unlock; |
1173 | } | 1166 | } |
1174 | 1167 | ||
1175 | status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode, | 1168 | status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode, |
1176 | data_alloc_bh); | 1169 | data_alloc_bh); |
1177 | if (status < 0) { | 1170 | if (status < 0) |
1178 | mlog_errno(status); | 1171 | mlog_errno(status); |
1179 | goto bail; | ||
1180 | } | ||
1181 | 1172 | ||
1182 | bail: | 1173 | ocfs2_commit_trans(osb, handle); |
1183 | if (handle) | ||
1184 | ocfs2_commit_trans(handle); | ||
1185 | 1174 | ||
1186 | if (data_alloc_inode) | 1175 | out_unlock: |
1187 | iput(data_alloc_inode); | 1176 | brelse(data_alloc_bh); |
1177 | ocfs2_meta_unlock(data_alloc_inode, 1); | ||
1188 | 1178 | ||
1189 | if (data_alloc_bh) | 1179 | out_mutex: |
1190 | brelse(data_alloc_bh); | 1180 | mutex_unlock(&data_alloc_inode->i_mutex); |
1181 | iput(data_alloc_inode); | ||
1191 | 1182 | ||
1183 | out: | ||
1192 | mlog_exit(status); | 1184 | mlog_exit(status); |
1193 | return status; | 1185 | return status; |
1194 | } | 1186 | } |
@@ -1205,10 +1197,12 @@ int ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
1205 | return status; | 1197 | return status; |
1206 | } | 1198 | } |
1207 | 1199 | ||
1208 | static void ocfs2_truncate_log_worker(void *data) | 1200 | static void ocfs2_truncate_log_worker(struct work_struct *work) |
1209 | { | 1201 | { |
1210 | int status; | 1202 | int status; |
1211 | struct ocfs2_super *osb = data; | 1203 | struct ocfs2_super *osb = |
1204 | container_of(work, struct ocfs2_super, | ||
1205 | osb_truncate_log_wq.work); | ||
1212 | 1206 | ||
1213 | mlog_entry_void(); | 1207 | mlog_entry_void(); |
1214 | 1208 | ||
@@ -1347,7 +1341,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
1347 | int i; | 1341 | int i; |
1348 | unsigned int clusters, num_recs, start_cluster; | 1342 | unsigned int clusters, num_recs, start_cluster; |
1349 | u64 start_blk; | 1343 | u64 start_blk; |
1350 | struct ocfs2_journal_handle *handle; | 1344 | handle_t *handle; |
1351 | struct inode *tl_inode = osb->osb_tl_inode; | 1345 | struct inode *tl_inode = osb->osb_tl_inode; |
1352 | struct ocfs2_truncate_log *tl; | 1346 | struct ocfs2_truncate_log *tl; |
1353 | 1347 | ||
@@ -1373,8 +1367,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
1373 | } | 1367 | } |
1374 | } | 1368 | } |
1375 | 1369 | ||
1376 | handle = ocfs2_start_trans(osb, NULL, | 1370 | handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_UPDATE); |
1377 | OCFS2_TRUNCATE_LOG_UPDATE); | ||
1378 | if (IS_ERR(handle)) { | 1371 | if (IS_ERR(handle)) { |
1379 | status = PTR_ERR(handle); | 1372 | status = PTR_ERR(handle); |
1380 | mlog_errno(status); | 1373 | mlog_errno(status); |
@@ -1387,7 +1380,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb, | |||
1387 | 1380 | ||
1388 | status = ocfs2_truncate_log_append(osb, handle, | 1381 | status = ocfs2_truncate_log_append(osb, handle, |
1389 | start_blk, clusters); | 1382 | start_blk, clusters); |
1390 | ocfs2_commit_trans(handle); | 1383 | ocfs2_commit_trans(osb, handle); |
1391 | if (status < 0) { | 1384 | if (status < 0) { |
1392 | mlog_errno(status); | 1385 | mlog_errno(status); |
1393 | goto bail_up; | 1386 | goto bail_up; |
@@ -1441,7 +1434,8 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb) | |||
1441 | /* ocfs2_truncate_log_shutdown keys on the existence of | 1434 | /* ocfs2_truncate_log_shutdown keys on the existence of |
1442 | * osb->osb_tl_inode so we don't set any of the osb variables | 1435 | * osb->osb_tl_inode so we don't set any of the osb variables |
1443 | * until we're sure all is well. */ | 1436 | * until we're sure all is well. */ |
1444 | INIT_WORK(&osb->osb_truncate_log_wq, ocfs2_truncate_log_worker, osb); | 1437 | INIT_DELAYED_WORK(&osb->osb_truncate_log_wq, |
1438 | ocfs2_truncate_log_worker); | ||
1445 | osb->osb_tl_bh = tl_bh; | 1439 | osb->osb_tl_bh = tl_bh; |
1446 | osb->osb_tl_inode = tl_inode; | 1440 | osb->osb_tl_inode = tl_inode; |
1447 | 1441 | ||
@@ -1543,7 +1537,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb, | |||
1543 | struct inode *inode, | 1537 | struct inode *inode, |
1544 | struct buffer_head *fe_bh, | 1538 | struct buffer_head *fe_bh, |
1545 | struct buffer_head *old_last_eb_bh, | 1539 | struct buffer_head *old_last_eb_bh, |
1546 | struct ocfs2_journal_handle *handle, | 1540 | handle_t *handle, |
1547 | struct ocfs2_truncate_context *tc) | 1541 | struct ocfs2_truncate_context *tc) |
1548 | { | 1542 | { |
1549 | int status, i, depth; | 1543 | int status, i, depth; |
@@ -1782,7 +1776,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, | |||
1782 | struct ocfs2_extent_block *eb; | 1776 | struct ocfs2_extent_block *eb; |
1783 | struct ocfs2_extent_list *el; | 1777 | struct ocfs2_extent_list *el; |
1784 | struct buffer_head *last_eb_bh; | 1778 | struct buffer_head *last_eb_bh; |
1785 | struct ocfs2_journal_handle *handle = NULL; | 1779 | handle_t *handle = NULL; |
1786 | struct inode *tl_inode = osb->osb_tl_inode; | 1780 | struct inode *tl_inode = osb->osb_tl_inode; |
1787 | 1781 | ||
1788 | mlog_entry_void(); | 1782 | mlog_entry_void(); |
@@ -1868,7 +1862,7 @@ start: | |||
1868 | 1862 | ||
1869 | credits = ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del, | 1863 | credits = ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del, |
1870 | fe, el); | 1864 | fe, el); |
1871 | handle = ocfs2_start_trans(osb, NULL, credits); | 1865 | handle = ocfs2_start_trans(osb, credits); |
1872 | if (IS_ERR(handle)) { | 1866 | if (IS_ERR(handle)) { |
1873 | status = PTR_ERR(handle); | 1867 | status = PTR_ERR(handle); |
1874 | handle = NULL; | 1868 | handle = NULL; |
@@ -1891,7 +1885,7 @@ start: | |||
1891 | mutex_unlock(&tl_inode->i_mutex); | 1885 | mutex_unlock(&tl_inode->i_mutex); |
1892 | tl_sem = 0; | 1886 | tl_sem = 0; |
1893 | 1887 | ||
1894 | ocfs2_commit_trans(handle); | 1888 | ocfs2_commit_trans(osb, handle); |
1895 | handle = NULL; | 1889 | handle = NULL; |
1896 | 1890 | ||
1897 | BUG_ON(le32_to_cpu(fe->i_clusters) < target_i_clusters); | 1891 | BUG_ON(le32_to_cpu(fe->i_clusters) < target_i_clusters); |
@@ -1906,7 +1900,7 @@ bail: | |||
1906 | mutex_unlock(&tl_inode->i_mutex); | 1900 | mutex_unlock(&tl_inode->i_mutex); |
1907 | 1901 | ||
1908 | if (handle) | 1902 | if (handle) |
1909 | ocfs2_commit_trans(handle); | 1903 | ocfs2_commit_trans(osb, handle); |
1910 | 1904 | ||
1911 | if (last_eb_bh) | 1905 | if (last_eb_bh) |
1912 | brelse(last_eb_bh); | 1906 | brelse(last_eb_bh); |
@@ -2011,10 +2005,7 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb, | |||
2011 | mutex_lock(&ext_alloc_inode->i_mutex); | 2005 | mutex_lock(&ext_alloc_inode->i_mutex); |
2012 | (*tc)->tc_ext_alloc_inode = ext_alloc_inode; | 2006 | (*tc)->tc_ext_alloc_inode = ext_alloc_inode; |
2013 | 2007 | ||
2014 | status = ocfs2_meta_lock(ext_alloc_inode, | 2008 | status = ocfs2_meta_lock(ext_alloc_inode, &ext_alloc_bh, 1); |
2015 | NULL, | ||
2016 | &ext_alloc_bh, | ||
2017 | 1); | ||
2018 | if (status < 0) { | 2009 | if (status < 0) { |
2019 | mlog_errno(status); | 2010 | mlog_errno(status); |
2020 | goto bail; | 2011 | goto bail; |
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 12ba897743f4..0b82e8044325 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | struct ocfs2_alloc_context; | 29 | struct ocfs2_alloc_context; |
30 | int ocfs2_insert_extent(struct ocfs2_super *osb, | 30 | int ocfs2_insert_extent(struct ocfs2_super *osb, |
31 | struct ocfs2_journal_handle *handle, | 31 | handle_t *handle, |
32 | struct inode *inode, | 32 | struct inode *inode, |
33 | struct buffer_head *fe_bh, | 33 | struct buffer_head *fe_bh, |
34 | u64 blkno, | 34 | u64 blkno, |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 3d7c082a8f58..2f7268e81520 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -200,7 +200,7 @@ static int ocfs2_readpage(struct file *file, struct page *page) | |||
200 | 200 | ||
201 | mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0)); | 201 | mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0)); |
202 | 202 | ||
203 | ret = ocfs2_meta_lock_with_page(inode, NULL, NULL, 0, page); | 203 | ret = ocfs2_meta_lock_with_page(inode, NULL, 0, page); |
204 | if (ret != 0) { | 204 | if (ret != 0) { |
205 | if (ret == AOP_TRUNCATED_PAGE) | 205 | if (ret == AOP_TRUNCATED_PAGE) |
206 | unlock = 0; | 206 | unlock = 0; |
@@ -305,7 +305,7 @@ static int ocfs2_prepare_write(struct file *file, struct page *page, | |||
305 | 305 | ||
306 | mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); | 306 | mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); |
307 | 307 | ||
308 | ret = ocfs2_meta_lock_with_page(inode, NULL, NULL, 0, page); | 308 | ret = ocfs2_meta_lock_with_page(inode, NULL, 0, page); |
309 | if (ret != 0) { | 309 | if (ret != 0) { |
310 | mlog_errno(ret); | 310 | mlog_errno(ret); |
311 | goto out; | 311 | goto out; |
@@ -355,16 +355,16 @@ static int walk_page_buffers( handle_t *handle, | |||
355 | return ret; | 355 | return ret; |
356 | } | 356 | } |
357 | 357 | ||
358 | struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, | 358 | handle_t *ocfs2_start_walk_page_trans(struct inode *inode, |
359 | struct page *page, | 359 | struct page *page, |
360 | unsigned from, | 360 | unsigned from, |
361 | unsigned to) | 361 | unsigned to) |
362 | { | 362 | { |
363 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 363 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
364 | struct ocfs2_journal_handle *handle = NULL; | 364 | handle_t *handle = NULL; |
365 | int ret = 0; | 365 | int ret = 0; |
366 | 366 | ||
367 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 367 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
368 | if (!handle) { | 368 | if (!handle) { |
369 | ret = -ENOMEM; | 369 | ret = -ENOMEM; |
370 | mlog_errno(ret); | 370 | mlog_errno(ret); |
@@ -372,7 +372,7 @@ struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, | |||
372 | } | 372 | } |
373 | 373 | ||
374 | if (ocfs2_should_order_data(inode)) { | 374 | if (ocfs2_should_order_data(inode)) { |
375 | ret = walk_page_buffers(handle->k_handle, | 375 | ret = walk_page_buffers(handle, |
376 | page_buffers(page), | 376 | page_buffers(page), |
377 | from, to, NULL, | 377 | from, to, NULL, |
378 | ocfs2_journal_dirty_data); | 378 | ocfs2_journal_dirty_data); |
@@ -382,7 +382,7 @@ struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, | |||
382 | out: | 382 | out: |
383 | if (ret) { | 383 | if (ret) { |
384 | if (handle) | 384 | if (handle) |
385 | ocfs2_commit_trans(handle); | 385 | ocfs2_commit_trans(osb, handle); |
386 | handle = ERR_PTR(ret); | 386 | handle = ERR_PTR(ret); |
387 | } | 387 | } |
388 | return handle; | 388 | return handle; |
@@ -394,7 +394,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page, | |||
394 | int ret; | 394 | int ret; |
395 | struct buffer_head *di_bh = NULL; | 395 | struct buffer_head *di_bh = NULL; |
396 | struct inode *inode = page->mapping->host; | 396 | struct inode *inode = page->mapping->host; |
397 | struct ocfs2_journal_handle *handle = NULL; | 397 | handle_t *handle = NULL; |
398 | struct ocfs2_dinode *di; | 398 | struct ocfs2_dinode *di; |
399 | 399 | ||
400 | mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); | 400 | mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); |
@@ -412,7 +412,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page, | |||
412 | * stale inode allocation image (i_size, i_clusters, etc). | 412 | * stale inode allocation image (i_size, i_clusters, etc). |
413 | */ | 413 | */ |
414 | 414 | ||
415 | ret = ocfs2_meta_lock_with_page(inode, NULL, &di_bh, 1, page); | 415 | ret = ocfs2_meta_lock_with_page(inode, &di_bh, 1, page); |
416 | if (ret != 0) { | 416 | if (ret != 0) { |
417 | mlog_errno(ret); | 417 | mlog_errno(ret); |
418 | goto out; | 418 | goto out; |
@@ -464,7 +464,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page, | |||
464 | } | 464 | } |
465 | 465 | ||
466 | out_commit: | 466 | out_commit: |
467 | ocfs2_commit_trans(handle); | 467 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
468 | out_unlock_data: | 468 | out_unlock_data: |
469 | ocfs2_data_unlock(inode, 1); | 469 | ocfs2_data_unlock(inode, 1); |
470 | out_unlock_meta: | 470 | out_unlock_meta: |
@@ -490,7 +490,7 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block) | |||
490 | * accessed concurrently from multiple nodes. | 490 | * accessed concurrently from multiple nodes. |
491 | */ | 491 | */ |
492 | if (!INODE_JOURNAL(inode)) { | 492 | if (!INODE_JOURNAL(inode)) { |
493 | err = ocfs2_meta_lock(inode, NULL, NULL, 0); | 493 | err = ocfs2_meta_lock(inode, NULL, 0); |
494 | if (err) { | 494 | if (err) { |
495 | if (err != -ENOENT) | 495 | if (err != -ENOENT) |
496 | mlog_errno(err); | 496 | mlog_errno(err); |
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h index e88c3f0b8fa9..f446a15eab88 100644 --- a/fs/ocfs2/aops.h +++ b/fs/ocfs2/aops.h | |||
@@ -25,7 +25,7 @@ | |||
25 | int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, | 25 | int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, |
26 | unsigned from, unsigned to); | 26 | unsigned from, unsigned to); |
27 | 27 | ||
28 | struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, | 28 | handle_t *ocfs2_start_walk_page_trans(struct inode *inode, |
29 | struct page *page, | 29 | struct page *page, |
30 | unsigned from, | 30 | unsigned from, |
31 | unsigned to); | 31 | unsigned to); |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 305cba3681fe..4cd9a9580456 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -141,7 +141,7 @@ struct o2hb_region { | |||
141 | * recognizes a node going up and down in one iteration */ | 141 | * recognizes a node going up and down in one iteration */ |
142 | u64 hr_generation; | 142 | u64 hr_generation; |
143 | 143 | ||
144 | struct work_struct hr_write_timeout_work; | 144 | struct delayed_work hr_write_timeout_work; |
145 | unsigned long hr_last_timeout_start; | 145 | unsigned long hr_last_timeout_start; |
146 | 146 | ||
147 | /* Used during o2hb_check_slot to hold a copy of the block | 147 | /* Used during o2hb_check_slot to hold a copy of the block |
@@ -156,9 +156,11 @@ struct o2hb_bio_wait_ctxt { | |||
156 | int wc_error; | 156 | int wc_error; |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static void o2hb_write_timeout(void *arg) | 159 | static void o2hb_write_timeout(struct work_struct *work) |
160 | { | 160 | { |
161 | struct o2hb_region *reg = arg; | 161 | struct o2hb_region *reg = |
162 | container_of(work, struct o2hb_region, | ||
163 | hr_write_timeout_work.work); | ||
162 | 164 | ||
163 | mlog(ML_ERROR, "Heartbeat write timeout to device %s after %u " | 165 | mlog(ML_ERROR, "Heartbeat write timeout to device %s after %u " |
164 | "milliseconds\n", reg->hr_dev_name, | 166 | "milliseconds\n", reg->hr_dev_name, |
@@ -1404,7 +1406,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1404 | goto out; | 1406 | goto out; |
1405 | } | 1407 | } |
1406 | 1408 | ||
1407 | INIT_WORK(®->hr_write_timeout_work, o2hb_write_timeout, reg); | 1409 | INIT_DELAYED_WORK(®->hr_write_timeout_work, o2hb_write_timeout); |
1408 | 1410 | ||
1409 | /* | 1411 | /* |
1410 | * A node is considered live after it has beat LIVE_THRESHOLD | 1412 | * A node is considered live after it has beat LIVE_THRESHOLD |
diff --git a/fs/ocfs2/cluster/quorum.c b/fs/ocfs2/cluster/quorum.c index 7bba98fbfc15..4705d659fe57 100644 --- a/fs/ocfs2/cluster/quorum.c +++ b/fs/ocfs2/cluster/quorum.c | |||
@@ -88,7 +88,7 @@ void o2quo_disk_timeout(void) | |||
88 | o2quo_fence_self(); | 88 | o2quo_fence_self(); |
89 | } | 89 | } |
90 | 90 | ||
91 | static void o2quo_make_decision(void *arg) | 91 | static void o2quo_make_decision(struct work_struct *work) |
92 | { | 92 | { |
93 | int quorum; | 93 | int quorum; |
94 | int lowest_hb, lowest_reachable = 0, fence = 0; | 94 | int lowest_hb, lowest_reachable = 0, fence = 0; |
@@ -306,7 +306,7 @@ void o2quo_init(void) | |||
306 | struct o2quo_state *qs = &o2quo_state; | 306 | struct o2quo_state *qs = &o2quo_state; |
307 | 307 | ||
308 | spin_lock_init(&qs->qs_lock); | 308 | spin_lock_init(&qs->qs_lock); |
309 | INIT_WORK(&qs->qs_work, o2quo_make_decision, NULL); | 309 | INIT_WORK(&qs->qs_work, o2quo_make_decision); |
310 | } | 310 | } |
311 | 311 | ||
312 | void o2quo_exit(void) | 312 | void o2quo_exit(void) |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index b650efa8c8be..9b3209dc0b16 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -140,11 +140,11 @@ static int o2net_sys_err_translations[O2NET_ERR_MAX] = | |||
140 | [O2NET_ERR_DIED] = -EHOSTDOWN,}; | 140 | [O2NET_ERR_DIED] = -EHOSTDOWN,}; |
141 | 141 | ||
142 | /* can't quite avoid *all* internal declarations :/ */ | 142 | /* can't quite avoid *all* internal declarations :/ */ |
143 | static void o2net_sc_connect_completed(void *arg); | 143 | static void o2net_sc_connect_completed(struct work_struct *work); |
144 | static void o2net_rx_until_empty(void *arg); | 144 | static void o2net_rx_until_empty(struct work_struct *work); |
145 | static void o2net_shutdown_sc(void *arg); | 145 | static void o2net_shutdown_sc(struct work_struct *work); |
146 | static void o2net_listen_data_ready(struct sock *sk, int bytes); | 146 | static void o2net_listen_data_ready(struct sock *sk, int bytes); |
147 | static void o2net_sc_send_keep_req(void *arg); | 147 | static void o2net_sc_send_keep_req(struct work_struct *work); |
148 | static void o2net_idle_timer(unsigned long data); | 148 | static void o2net_idle_timer(unsigned long data); |
149 | static void o2net_sc_postpone_idle(struct o2net_sock_container *sc); | 149 | static void o2net_sc_postpone_idle(struct o2net_sock_container *sc); |
150 | 150 | ||
@@ -308,10 +308,10 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) | |||
308 | o2nm_node_get(node); | 308 | o2nm_node_get(node); |
309 | sc->sc_node = node; | 309 | sc->sc_node = node; |
310 | 310 | ||
311 | INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed, sc); | 311 | INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed); |
312 | INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty, sc); | 312 | INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty); |
313 | INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc, sc); | 313 | INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc); |
314 | INIT_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req, sc); | 314 | INIT_DELAYED_WORK(&sc->sc_keepalive_work, o2net_sc_send_keep_req); |
315 | 315 | ||
316 | init_timer(&sc->sc_idle_timeout); | 316 | init_timer(&sc->sc_idle_timeout); |
317 | sc->sc_idle_timeout.function = o2net_idle_timer; | 317 | sc->sc_idle_timeout.function = o2net_idle_timer; |
@@ -342,7 +342,7 @@ static void o2net_sc_queue_work(struct o2net_sock_container *sc, | |||
342 | sc_put(sc); | 342 | sc_put(sc); |
343 | } | 343 | } |
344 | static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, | 344 | static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, |
345 | struct work_struct *work, | 345 | struct delayed_work *work, |
346 | int delay) | 346 | int delay) |
347 | { | 347 | { |
348 | sc_get(sc); | 348 | sc_get(sc); |
@@ -350,7 +350,7 @@ static void o2net_sc_queue_delayed_work(struct o2net_sock_container *sc, | |||
350 | sc_put(sc); | 350 | sc_put(sc); |
351 | } | 351 | } |
352 | static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc, | 352 | static void o2net_sc_cancel_delayed_work(struct o2net_sock_container *sc, |
353 | struct work_struct *work) | 353 | struct delayed_work *work) |
354 | { | 354 | { |
355 | if (cancel_delayed_work(work)) | 355 | if (cancel_delayed_work(work)) |
356 | sc_put(sc); | 356 | sc_put(sc); |
@@ -564,9 +564,11 @@ static void o2net_ensure_shutdown(struct o2net_node *nn, | |||
564 | * ourselves as state_change couldn't get the nn_lock and call set_nn_state | 564 | * ourselves as state_change couldn't get the nn_lock and call set_nn_state |
565 | * itself. | 565 | * itself. |
566 | */ | 566 | */ |
567 | static void o2net_shutdown_sc(void *arg) | 567 | static void o2net_shutdown_sc(struct work_struct *work) |
568 | { | 568 | { |
569 | struct o2net_sock_container *sc = arg; | 569 | struct o2net_sock_container *sc = |
570 | container_of(work, struct o2net_sock_container, | ||
571 | sc_shutdown_work); | ||
570 | struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); | 572 | struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); |
571 | 573 | ||
572 | sclog(sc, "shutting down\n"); | 574 | sclog(sc, "shutting down\n"); |
@@ -1201,9 +1203,10 @@ out: | |||
1201 | /* this work func is triggerd by data ready. it reads until it can read no | 1203 | /* this work func is triggerd by data ready. it reads until it can read no |
1202 | * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing | 1204 | * more. it interprets 0, eof, as fatal. if data_ready hits while we're doing |
1203 | * our work the work struct will be marked and we'll be called again. */ | 1205 | * our work the work struct will be marked and we'll be called again. */ |
1204 | static void o2net_rx_until_empty(void *arg) | 1206 | static void o2net_rx_until_empty(struct work_struct *work) |
1205 | { | 1207 | { |
1206 | struct o2net_sock_container *sc = arg; | 1208 | struct o2net_sock_container *sc = |
1209 | container_of(work, struct o2net_sock_container, sc_rx_work); | ||
1207 | int ret; | 1210 | int ret; |
1208 | 1211 | ||
1209 | do { | 1212 | do { |
@@ -1249,9 +1252,11 @@ static int o2net_set_nodelay(struct socket *sock) | |||
1249 | 1252 | ||
1250 | /* called when a connect completes and after a sock is accepted. the | 1253 | /* called when a connect completes and after a sock is accepted. the |
1251 | * rx path will see the response and mark the sc valid */ | 1254 | * rx path will see the response and mark the sc valid */ |
1252 | static void o2net_sc_connect_completed(void *arg) | 1255 | static void o2net_sc_connect_completed(struct work_struct *work) |
1253 | { | 1256 | { |
1254 | struct o2net_sock_container *sc = arg; | 1257 | struct o2net_sock_container *sc = |
1258 | container_of(work, struct o2net_sock_container, | ||
1259 | sc_connect_work); | ||
1255 | 1260 | ||
1256 | mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", | 1261 | mlog(ML_MSG, "sc sending handshake with ver %llu id %llx\n", |
1257 | (unsigned long long)O2NET_PROTOCOL_VERSION, | 1262 | (unsigned long long)O2NET_PROTOCOL_VERSION, |
@@ -1262,9 +1267,11 @@ static void o2net_sc_connect_completed(void *arg) | |||
1262 | } | 1267 | } |
1263 | 1268 | ||
1264 | /* this is called as a work_struct func. */ | 1269 | /* this is called as a work_struct func. */ |
1265 | static void o2net_sc_send_keep_req(void *arg) | 1270 | static void o2net_sc_send_keep_req(struct work_struct *work) |
1266 | { | 1271 | { |
1267 | struct o2net_sock_container *sc = arg; | 1272 | struct o2net_sock_container *sc = |
1273 | container_of(work, struct o2net_sock_container, | ||
1274 | sc_keepalive_work.work); | ||
1268 | 1275 | ||
1269 | o2net_sendpage(sc, o2net_keep_req, sizeof(*o2net_keep_req)); | 1276 | o2net_sendpage(sc, o2net_keep_req, sizeof(*o2net_keep_req)); |
1270 | sc_put(sc); | 1277 | sc_put(sc); |
@@ -1314,14 +1321,15 @@ static void o2net_sc_postpone_idle(struct o2net_sock_container *sc) | |||
1314 | * having a connect attempt fail, etc. This centralizes the logic which decides | 1321 | * having a connect attempt fail, etc. This centralizes the logic which decides |
1315 | * if a connect attempt should be made or if we should give up and all future | 1322 | * if a connect attempt should be made or if we should give up and all future |
1316 | * transmit attempts should fail */ | 1323 | * transmit attempts should fail */ |
1317 | static void o2net_start_connect(void *arg) | 1324 | static void o2net_start_connect(struct work_struct *work) |
1318 | { | 1325 | { |
1319 | struct o2net_node *nn = arg; | 1326 | struct o2net_node *nn = |
1327 | container_of(work, struct o2net_node, nn_connect_work.work); | ||
1320 | struct o2net_sock_container *sc = NULL; | 1328 | struct o2net_sock_container *sc = NULL; |
1321 | struct o2nm_node *node = NULL, *mynode = NULL; | 1329 | struct o2nm_node *node = NULL, *mynode = NULL; |
1322 | struct socket *sock = NULL; | 1330 | struct socket *sock = NULL; |
1323 | struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; | 1331 | struct sockaddr_in myaddr = {0, }, remoteaddr = {0, }; |
1324 | int ret = 0; | 1332 | int ret = 0, stop; |
1325 | 1333 | ||
1326 | /* if we're greater we initiate tx, otherwise we accept */ | 1334 | /* if we're greater we initiate tx, otherwise we accept */ |
1327 | if (o2nm_this_node() <= o2net_num_from_nn(nn)) | 1335 | if (o2nm_this_node() <= o2net_num_from_nn(nn)) |
@@ -1342,10 +1350,9 @@ static void o2net_start_connect(void *arg) | |||
1342 | 1350 | ||
1343 | spin_lock(&nn->nn_lock); | 1351 | spin_lock(&nn->nn_lock); |
1344 | /* see if we already have one pending or have given up */ | 1352 | /* see if we already have one pending or have given up */ |
1345 | if (nn->nn_sc || nn->nn_persistent_error) | 1353 | stop = (nn->nn_sc || nn->nn_persistent_error); |
1346 | arg = NULL; | ||
1347 | spin_unlock(&nn->nn_lock); | 1354 | spin_unlock(&nn->nn_lock); |
1348 | if (arg == NULL) /* *shrug*, needed some indicator */ | 1355 | if (stop) |
1349 | goto out; | 1356 | goto out; |
1350 | 1357 | ||
1351 | nn->nn_last_connect_attempt = jiffies; | 1358 | nn->nn_last_connect_attempt = jiffies; |
@@ -1421,9 +1428,10 @@ out: | |||
1421 | return; | 1428 | return; |
1422 | } | 1429 | } |
1423 | 1430 | ||
1424 | static void o2net_connect_expired(void *arg) | 1431 | static void o2net_connect_expired(struct work_struct *work) |
1425 | { | 1432 | { |
1426 | struct o2net_node *nn = arg; | 1433 | struct o2net_node *nn = |
1434 | container_of(work, struct o2net_node, nn_connect_expired.work); | ||
1427 | 1435 | ||
1428 | spin_lock(&nn->nn_lock); | 1436 | spin_lock(&nn->nn_lock); |
1429 | if (!nn->nn_sc_valid) { | 1437 | if (!nn->nn_sc_valid) { |
@@ -1436,9 +1444,10 @@ static void o2net_connect_expired(void *arg) | |||
1436 | spin_unlock(&nn->nn_lock); | 1444 | spin_unlock(&nn->nn_lock); |
1437 | } | 1445 | } |
1438 | 1446 | ||
1439 | static void o2net_still_up(void *arg) | 1447 | static void o2net_still_up(struct work_struct *work) |
1440 | { | 1448 | { |
1441 | struct o2net_node *nn = arg; | 1449 | struct o2net_node *nn = |
1450 | container_of(work, struct o2net_node, nn_still_up.work); | ||
1442 | 1451 | ||
1443 | o2quo_hb_still_up(o2net_num_from_nn(nn)); | 1452 | o2quo_hb_still_up(o2net_num_from_nn(nn)); |
1444 | } | 1453 | } |
@@ -1644,9 +1653,9 @@ out: | |||
1644 | return ret; | 1653 | return ret; |
1645 | } | 1654 | } |
1646 | 1655 | ||
1647 | static void o2net_accept_many(void *arg) | 1656 | static void o2net_accept_many(struct work_struct *work) |
1648 | { | 1657 | { |
1649 | struct socket *sock = arg; | 1658 | struct socket *sock = o2net_listen_sock; |
1650 | while (o2net_accept_one(sock) == 0) | 1659 | while (o2net_accept_one(sock) == 0) |
1651 | cond_resched(); | 1660 | cond_resched(); |
1652 | } | 1661 | } |
@@ -1700,7 +1709,7 @@ static int o2net_open_listening_sock(__be16 port) | |||
1700 | write_unlock_bh(&sock->sk->sk_callback_lock); | 1709 | write_unlock_bh(&sock->sk->sk_callback_lock); |
1701 | 1710 | ||
1702 | o2net_listen_sock = sock; | 1711 | o2net_listen_sock = sock; |
1703 | INIT_WORK(&o2net_listen_work, o2net_accept_many, sock); | 1712 | INIT_WORK(&o2net_listen_work, o2net_accept_many); |
1704 | 1713 | ||
1705 | sock->sk->sk_reuse = 1; | 1714 | sock->sk->sk_reuse = 1; |
1706 | ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); | 1715 | ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); |
@@ -1819,9 +1828,10 @@ int o2net_init(void) | |||
1819 | struct o2net_node *nn = o2net_nn_from_num(i); | 1828 | struct o2net_node *nn = o2net_nn_from_num(i); |
1820 | 1829 | ||
1821 | spin_lock_init(&nn->nn_lock); | 1830 | spin_lock_init(&nn->nn_lock); |
1822 | INIT_WORK(&nn->nn_connect_work, o2net_start_connect, nn); | 1831 | INIT_DELAYED_WORK(&nn->nn_connect_work, o2net_start_connect); |
1823 | INIT_WORK(&nn->nn_connect_expired, o2net_connect_expired, nn); | 1832 | INIT_DELAYED_WORK(&nn->nn_connect_expired, |
1824 | INIT_WORK(&nn->nn_still_up, o2net_still_up, nn); | 1833 | o2net_connect_expired); |
1834 | INIT_DELAYED_WORK(&nn->nn_still_up, o2net_still_up); | ||
1825 | /* until we see hb from a node we'll return einval */ | 1835 | /* until we see hb from a node we'll return einval */ |
1826 | nn->nn_persistent_error = -ENOTCONN; | 1836 | nn->nn_persistent_error = -ENOTCONN; |
1827 | init_waitqueue_head(&nn->nn_sc_wq); | 1837 | init_waitqueue_head(&nn->nn_sc_wq); |
diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h index 4b46aac7d243..daebbd3a2c8c 100644 --- a/fs/ocfs2/cluster/tcp_internal.h +++ b/fs/ocfs2/cluster/tcp_internal.h | |||
@@ -86,18 +86,18 @@ struct o2net_node { | |||
86 | * connect attempt fails and so can be self-arming. shutdown is | 86 | * connect attempt fails and so can be self-arming. shutdown is |
87 | * careful to first mark the nn such that no connects will be attempted | 87 | * careful to first mark the nn such that no connects will be attempted |
88 | * before canceling delayed connect work and flushing the queue. */ | 88 | * before canceling delayed connect work and flushing the queue. */ |
89 | struct work_struct nn_connect_work; | 89 | struct delayed_work nn_connect_work; |
90 | unsigned long nn_last_connect_attempt; | 90 | unsigned long nn_last_connect_attempt; |
91 | 91 | ||
92 | /* this is queued as nodes come up and is canceled when a connection is | 92 | /* this is queued as nodes come up and is canceled when a connection is |
93 | * established. this expiring gives up on the node and errors out | 93 | * established. this expiring gives up on the node and errors out |
94 | * transmits */ | 94 | * transmits */ |
95 | struct work_struct nn_connect_expired; | 95 | struct delayed_work nn_connect_expired; |
96 | 96 | ||
97 | /* after we give up on a socket we wait a while before deciding | 97 | /* after we give up on a socket we wait a while before deciding |
98 | * that it is still heartbeating and that we should do some | 98 | * that it is still heartbeating and that we should do some |
99 | * quorum work */ | 99 | * quorum work */ |
100 | struct work_struct nn_still_up; | 100 | struct delayed_work nn_still_up; |
101 | }; | 101 | }; |
102 | 102 | ||
103 | struct o2net_sock_container { | 103 | struct o2net_sock_container { |
@@ -129,7 +129,7 @@ struct o2net_sock_container { | |||
129 | struct work_struct sc_shutdown_work; | 129 | struct work_struct sc_shutdown_work; |
130 | 130 | ||
131 | struct timer_list sc_idle_timeout; | 131 | struct timer_list sc_idle_timeout; |
132 | struct work_struct sc_keepalive_work; | 132 | struct delayed_work sc_keepalive_work; |
133 | 133 | ||
134 | unsigned sc_handshake_ok:1; | 134 | unsigned sc_handshake_ok:1; |
135 | 135 | ||
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 04e01915b86e..baad2aa27c14 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -82,6 +82,7 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
82 | struct inode *inode = filp->f_dentry->d_inode; | 82 | struct inode *inode = filp->f_dentry->d_inode; |
83 | struct super_block * sb = inode->i_sb; | 83 | struct super_block * sb = inode->i_sb; |
84 | unsigned int ra_sectors = 16; | 84 | unsigned int ra_sectors = 16; |
85 | int lock_level = 0; | ||
85 | 86 | ||
86 | mlog_entry("dirino=%llu\n", | 87 | mlog_entry("dirino=%llu\n", |
87 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | 88 | (unsigned long long)OCFS2_I(inode)->ip_blkno); |
@@ -89,7 +90,15 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
89 | stored = 0; | 90 | stored = 0; |
90 | bh = NULL; | 91 | bh = NULL; |
91 | 92 | ||
92 | error = ocfs2_meta_lock(inode, NULL, NULL, 0); | 93 | error = ocfs2_meta_lock_atime(inode, filp->f_vfsmnt, &lock_level); |
94 | if (lock_level && error >= 0) { | ||
95 | /* We release EX lock which used to update atime | ||
96 | * and get PR lock again to reduce contention | ||
97 | * on commonly accessed directories. */ | ||
98 | ocfs2_meta_unlock(inode, 1); | ||
99 | lock_level = 0; | ||
100 | error = ocfs2_meta_lock(inode, NULL, 0); | ||
101 | } | ||
93 | if (error < 0) { | 102 | if (error < 0) { |
94 | if (error != -ENOENT) | 103 | if (error != -ENOENT) |
95 | mlog_errno(error); | 104 | mlog_errno(error); |
@@ -198,7 +207,7 @@ revalidate: | |||
198 | 207 | ||
199 | stored = 0; | 208 | stored = 0; |
200 | bail: | 209 | bail: |
201 | ocfs2_meta_unlock(inode, 0); | 210 | ocfs2_meta_unlock(inode, lock_level); |
202 | 211 | ||
203 | bail_nolock: | 212 | bail_nolock: |
204 | mlog_exit(stored); | 213 | mlog_exit(stored); |
@@ -340,7 +349,7 @@ int ocfs2_empty_dir(struct inode *inode) | |||
340 | 349 | ||
341 | /* returns a bh of the 1st new block in the allocation. */ | 350 | /* returns a bh of the 1st new block in the allocation. */ |
342 | int ocfs2_do_extend_dir(struct super_block *sb, | 351 | int ocfs2_do_extend_dir(struct super_block *sb, |
343 | struct ocfs2_journal_handle *handle, | 352 | handle_t *handle, |
344 | struct inode *dir, | 353 | struct inode *dir, |
345 | struct buffer_head *parent_fe_bh, | 354 | struct buffer_head *parent_fe_bh, |
346 | struct ocfs2_alloc_context *data_ac, | 355 | struct ocfs2_alloc_context *data_ac, |
@@ -398,7 +407,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
398 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; | 407 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; |
399 | struct ocfs2_alloc_context *data_ac = NULL; | 408 | struct ocfs2_alloc_context *data_ac = NULL; |
400 | struct ocfs2_alloc_context *meta_ac = NULL; | 409 | struct ocfs2_alloc_context *meta_ac = NULL; |
401 | struct ocfs2_journal_handle *handle = NULL; | 410 | handle_t *handle = NULL; |
402 | struct buffer_head *new_bh = NULL; | 411 | struct buffer_head *new_bh = NULL; |
403 | struct ocfs2_dir_entry * de; | 412 | struct ocfs2_dir_entry * de; |
404 | struct super_block *sb = osb->sb; | 413 | struct super_block *sb = osb->sb; |
@@ -409,13 +418,6 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
409 | mlog(0, "extending dir %llu (i_size = %lld)\n", | 418 | mlog(0, "extending dir %llu (i_size = %lld)\n", |
410 | (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); | 419 | (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); |
411 | 420 | ||
412 | handle = ocfs2_alloc_handle(osb); | ||
413 | if (handle == NULL) { | ||
414 | status = -ENOMEM; | ||
415 | mlog_errno(status); | ||
416 | goto bail; | ||
417 | } | ||
418 | |||
419 | /* dir->i_size is always block aligned. */ | 421 | /* dir->i_size is always block aligned. */ |
420 | spin_lock(&OCFS2_I(dir)->ip_lock); | 422 | spin_lock(&OCFS2_I(dir)->ip_lock); |
421 | if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { | 423 | if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { |
@@ -428,8 +430,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
428 | } | 430 | } |
429 | 431 | ||
430 | if (!num_free_extents) { | 432 | if (!num_free_extents) { |
431 | status = ocfs2_reserve_new_metadata(osb, handle, | 433 | status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac); |
432 | fe, &meta_ac); | ||
433 | if (status < 0) { | 434 | if (status < 0) { |
434 | if (status != -ENOSPC) | 435 | if (status != -ENOSPC) |
435 | mlog_errno(status); | 436 | mlog_errno(status); |
@@ -437,7 +438,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
437 | } | 438 | } |
438 | } | 439 | } |
439 | 440 | ||
440 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 441 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
441 | if (status < 0) { | 442 | if (status < 0) { |
442 | if (status != -ENOSPC) | 443 | if (status != -ENOSPC) |
443 | mlog_errno(status); | 444 | mlog_errno(status); |
@@ -450,7 +451,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
450 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; | 451 | credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; |
451 | } | 452 | } |
452 | 453 | ||
453 | handle = ocfs2_start_trans(osb, handle, credits); | 454 | handle = ocfs2_start_trans(osb, credits); |
454 | if (IS_ERR(handle)) { | 455 | if (IS_ERR(handle)) { |
455 | status = PTR_ERR(handle); | 456 | status = PTR_ERR(handle); |
456 | handle = NULL; | 457 | handle = NULL; |
@@ -496,7 +497,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb, | |||
496 | get_bh(*new_de_bh); | 497 | get_bh(*new_de_bh); |
497 | bail: | 498 | bail: |
498 | if (handle) | 499 | if (handle) |
499 | ocfs2_commit_trans(handle); | 500 | ocfs2_commit_trans(osb, handle); |
500 | 501 | ||
501 | if (data_ac) | 502 | if (data_ac) |
502 | ocfs2_free_alloc_context(data_ac); | 503 | ocfs2_free_alloc_context(data_ac); |
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h index 5f614ec9649c..3f67e146864a 100644 --- a/fs/ocfs2/dir.h +++ b/fs/ocfs2/dir.h | |||
@@ -45,7 +45,7 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb, | |||
45 | struct buffer_head **ret_de_bh); | 45 | struct buffer_head **ret_de_bh); |
46 | struct ocfs2_alloc_context; | 46 | struct ocfs2_alloc_context; |
47 | int ocfs2_do_extend_dir(struct super_block *sb, | 47 | int ocfs2_do_extend_dir(struct super_block *sb, |
48 | struct ocfs2_journal_handle *handle, | 48 | handle_t *handle, |
49 | struct inode *dir, | 49 | struct inode *dir, |
50 | struct buffer_head *parent_fe_bh, | 50 | struct buffer_head *parent_fe_bh, |
51 | struct ocfs2_alloc_context *data_ac, | 51 | struct ocfs2_alloc_context *data_ac, |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index fa968180b072..6b6ff76538c5 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
@@ -153,7 +153,7 @@ static inline struct hlist_head *dlm_lockres_hash(struct dlm_ctxt *dlm, unsigned | |||
153 | * called functions that cannot be directly called from the | 153 | * called functions that cannot be directly called from the |
154 | * net message handlers for some reason, usually because | 154 | * net message handlers for some reason, usually because |
155 | * they need to send net messages of their own. */ | 155 | * they need to send net messages of their own. */ |
156 | void dlm_dispatch_work(void *data); | 156 | void dlm_dispatch_work(struct work_struct *work); |
157 | 157 | ||
158 | struct dlm_lock_resource; | 158 | struct dlm_lock_resource; |
159 | struct dlm_work_item; | 159 | struct dlm_work_item; |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 8d1065f8b3bd..420a375a3949 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -68,7 +68,8 @@ static void **dlm_alloc_pagevec(int pages) | |||
68 | goto out_free; | 68 | goto out_free; |
69 | 69 | ||
70 | mlog(0, "Allocated DLM hash pagevec; %d pages (%lu expected), %lu buckets per page\n", | 70 | mlog(0, "Allocated DLM hash pagevec; %d pages (%lu expected), %lu buckets per page\n", |
71 | pages, DLM_HASH_PAGES, (unsigned long)DLM_BUCKETS_PER_PAGE); | 71 | pages, (unsigned long)DLM_HASH_PAGES, |
72 | (unsigned long)DLM_BUCKETS_PER_PAGE); | ||
72 | return vec; | 73 | return vec; |
73 | out_free: | 74 | out_free: |
74 | dlm_free_pagevec(vec, i); | 75 | dlm_free_pagevec(vec, i); |
@@ -1296,7 +1297,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain, | |||
1296 | 1297 | ||
1297 | spin_lock_init(&dlm->work_lock); | 1298 | spin_lock_init(&dlm->work_lock); |
1298 | INIT_LIST_HEAD(&dlm->work_list); | 1299 | INIT_LIST_HEAD(&dlm->work_list); |
1299 | INIT_WORK(&dlm->dispatched_work, dlm_dispatch_work, dlm); | 1300 | INIT_WORK(&dlm->dispatched_work, dlm_dispatch_work); |
1300 | 1301 | ||
1301 | kref_init(&dlm->dlm_refs); | 1302 | kref_init(&dlm->dlm_refs); |
1302 | dlm->dlm_state = DLM_CTXT_NEW; | 1303 | dlm->dlm_state = DLM_CTXT_NEW; |
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index 16b8d1ba7066..941acf14e61f 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c | |||
@@ -66,7 +66,7 @@ static struct file_operations dlmfs_file_operations; | |||
66 | static struct inode_operations dlmfs_dir_inode_operations; | 66 | static struct inode_operations dlmfs_dir_inode_operations; |
67 | static struct inode_operations dlmfs_root_inode_operations; | 67 | static struct inode_operations dlmfs_root_inode_operations; |
68 | static struct inode_operations dlmfs_file_inode_operations; | 68 | static struct inode_operations dlmfs_file_inode_operations; |
69 | static kmem_cache_t *dlmfs_inode_cache; | 69 | static struct kmem_cache *dlmfs_inode_cache; |
70 | 70 | ||
71 | struct workqueue_struct *user_dlm_worker; | 71 | struct workqueue_struct *user_dlm_worker; |
72 | 72 | ||
@@ -257,7 +257,7 @@ static ssize_t dlmfs_file_write(struct file *filp, | |||
257 | } | 257 | } |
258 | 258 | ||
259 | static void dlmfs_init_once(void *foo, | 259 | static void dlmfs_init_once(void *foo, |
260 | kmem_cache_t *cachep, | 260 | struct kmem_cache *cachep, |
261 | unsigned long flags) | 261 | unsigned long flags) |
262 | { | 262 | { |
263 | struct dlmfs_inode_private *ip = | 263 | struct dlmfs_inode_private *ip = |
@@ -276,7 +276,7 @@ static struct inode *dlmfs_alloc_inode(struct super_block *sb) | |||
276 | { | 276 | { |
277 | struct dlmfs_inode_private *ip; | 277 | struct dlmfs_inode_private *ip; |
278 | 278 | ||
279 | ip = kmem_cache_alloc(dlmfs_inode_cache, SLAB_NOFS); | 279 | ip = kmem_cache_alloc(dlmfs_inode_cache, GFP_NOFS); |
280 | if (!ip) | 280 | if (!ip) |
281 | return NULL; | 281 | return NULL; |
282 | 282 | ||
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index f784177b6241..856012b4fa49 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -221,7 +221,7 @@ EXPORT_SYMBOL_GPL(dlm_dump_all_mles); | |||
221 | #endif /* 0 */ | 221 | #endif /* 0 */ |
222 | 222 | ||
223 | 223 | ||
224 | static kmem_cache_t *dlm_mle_cache = NULL; | 224 | static struct kmem_cache *dlm_mle_cache = NULL; |
225 | 225 | ||
226 | 226 | ||
227 | static void dlm_mle_release(struct kref *kref); | 227 | static void dlm_mle_release(struct kref *kref); |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 9d950d7cea38..fb3e2b0817f1 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -153,9 +153,10 @@ static inline void dlm_reset_recovery(struct dlm_ctxt *dlm) | |||
153 | } | 153 | } |
154 | 154 | ||
155 | /* Worker function used during recovery. */ | 155 | /* Worker function used during recovery. */ |
156 | void dlm_dispatch_work(void *data) | 156 | void dlm_dispatch_work(struct work_struct *work) |
157 | { | 157 | { |
158 | struct dlm_ctxt *dlm = (struct dlm_ctxt *)data; | 158 | struct dlm_ctxt *dlm = |
159 | container_of(work, struct dlm_ctxt, dispatched_work); | ||
159 | LIST_HEAD(tmp_list); | 160 | LIST_HEAD(tmp_list); |
160 | struct list_head *iter, *iter2; | 161 | struct list_head *iter, *iter2; |
161 | struct dlm_work_item *item; | 162 | struct dlm_work_item *item; |
diff --git a/fs/ocfs2/dlm/userdlm.c b/fs/ocfs2/dlm/userdlm.c index eead48bbfac6..7d2f578b267d 100644 --- a/fs/ocfs2/dlm/userdlm.c +++ b/fs/ocfs2/dlm/userdlm.c | |||
@@ -171,15 +171,14 @@ static inline void user_dlm_grab_inode_ref(struct user_lock_res *lockres) | |||
171 | BUG(); | 171 | BUG(); |
172 | } | 172 | } |
173 | 173 | ||
174 | static void user_dlm_unblock_lock(void *opaque); | 174 | static void user_dlm_unblock_lock(struct work_struct *work); |
175 | 175 | ||
176 | static void __user_dlm_queue_lockres(struct user_lock_res *lockres) | 176 | static void __user_dlm_queue_lockres(struct user_lock_res *lockres) |
177 | { | 177 | { |
178 | if (!(lockres->l_flags & USER_LOCK_QUEUED)) { | 178 | if (!(lockres->l_flags & USER_LOCK_QUEUED)) { |
179 | user_dlm_grab_inode_ref(lockres); | 179 | user_dlm_grab_inode_ref(lockres); |
180 | 180 | ||
181 | INIT_WORK(&lockres->l_work, user_dlm_unblock_lock, | 181 | INIT_WORK(&lockres->l_work, user_dlm_unblock_lock); |
182 | lockres); | ||
183 | 182 | ||
184 | queue_work(user_dlm_worker, &lockres->l_work); | 183 | queue_work(user_dlm_worker, &lockres->l_work); |
185 | lockres->l_flags |= USER_LOCK_QUEUED; | 184 | lockres->l_flags |= USER_LOCK_QUEUED; |
@@ -279,10 +278,11 @@ static inline void user_dlm_drop_inode_ref(struct user_lock_res *lockres) | |||
279 | iput(inode); | 278 | iput(inode); |
280 | } | 279 | } |
281 | 280 | ||
282 | static void user_dlm_unblock_lock(void *opaque) | 281 | static void user_dlm_unblock_lock(struct work_struct *work) |
283 | { | 282 | { |
284 | int new_level, status; | 283 | int new_level, status; |
285 | struct user_lock_res *lockres = (struct user_lock_res *) opaque; | 284 | struct user_lock_res *lockres = |
285 | container_of(work, struct user_lock_res, l_work); | ||
286 | struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres); | 286 | struct dlm_ctxt *dlm = dlm_ctxt_from_user_lockres(lockres); |
287 | 287 | ||
288 | mlog(0, "processing lockres %.*s\n", lockres->l_namelen, | 288 | mlog(0, "processing lockres %.*s\n", lockres->l_namelen, |
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 8801e41afe80..69fba16efbd1 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include "dcache.h" | 49 | #include "dcache.h" |
50 | #include "dlmglue.h" | 50 | #include "dlmglue.h" |
51 | #include "extent_map.h" | 51 | #include "extent_map.h" |
52 | #include "file.h" | ||
52 | #include "heartbeat.h" | 53 | #include "heartbeat.h" |
53 | #include "inode.h" | 54 | #include "inode.h" |
54 | #include "journal.h" | 55 | #include "journal.h" |
@@ -1063,10 +1064,10 @@ static void ocfs2_cluster_unlock(struct ocfs2_super *osb, | |||
1063 | mlog_exit_void(); | 1064 | mlog_exit_void(); |
1064 | } | 1065 | } |
1065 | 1066 | ||
1066 | int ocfs2_create_new_lock(struct ocfs2_super *osb, | 1067 | static int ocfs2_create_new_lock(struct ocfs2_super *osb, |
1067 | struct ocfs2_lock_res *lockres, | 1068 | struct ocfs2_lock_res *lockres, |
1068 | int ex, | 1069 | int ex, |
1069 | int local) | 1070 | int local) |
1070 | { | 1071 | { |
1071 | int level = ex ? LKM_EXMODE : LKM_PRMODE; | 1072 | int level = ex ? LKM_EXMODE : LKM_PRMODE; |
1072 | unsigned long flags; | 1073 | unsigned long flags; |
@@ -1579,7 +1580,6 @@ static int ocfs2_assign_bh(struct inode *inode, | |||
1579 | * the result of the lock will be communicated via the callback. | 1580 | * the result of the lock will be communicated via the callback. |
1580 | */ | 1581 | */ |
1581 | int ocfs2_meta_lock_full(struct inode *inode, | 1582 | int ocfs2_meta_lock_full(struct inode *inode, |
1582 | struct ocfs2_journal_handle *handle, | ||
1583 | struct buffer_head **ret_bh, | 1583 | struct buffer_head **ret_bh, |
1584 | int ex, | 1584 | int ex, |
1585 | int arg_flags) | 1585 | int arg_flags) |
@@ -1668,12 +1668,6 @@ int ocfs2_meta_lock_full(struct inode *inode, | |||
1668 | } | 1668 | } |
1669 | } | 1669 | } |
1670 | 1670 | ||
1671 | if (handle) { | ||
1672 | status = ocfs2_handle_add_lock(handle, inode); | ||
1673 | if (status < 0) | ||
1674 | mlog_errno(status); | ||
1675 | } | ||
1676 | |||
1677 | bail: | 1671 | bail: |
1678 | if (status < 0) { | 1672 | if (status < 0) { |
1679 | if (ret_bh && (*ret_bh)) { | 1673 | if (ret_bh && (*ret_bh)) { |
@@ -1713,18 +1707,16 @@ bail: | |||
1713 | * the lock inversion simply. | 1707 | * the lock inversion simply. |
1714 | */ | 1708 | */ |
1715 | int ocfs2_meta_lock_with_page(struct inode *inode, | 1709 | int ocfs2_meta_lock_with_page(struct inode *inode, |
1716 | struct ocfs2_journal_handle *handle, | ||
1717 | struct buffer_head **ret_bh, | 1710 | struct buffer_head **ret_bh, |
1718 | int ex, | 1711 | int ex, |
1719 | struct page *page) | 1712 | struct page *page) |
1720 | { | 1713 | { |
1721 | int ret; | 1714 | int ret; |
1722 | 1715 | ||
1723 | ret = ocfs2_meta_lock_full(inode, handle, ret_bh, ex, | 1716 | ret = ocfs2_meta_lock_full(inode, ret_bh, ex, OCFS2_LOCK_NONBLOCK); |
1724 | OCFS2_LOCK_NONBLOCK); | ||
1725 | if (ret == -EAGAIN) { | 1717 | if (ret == -EAGAIN) { |
1726 | unlock_page(page); | 1718 | unlock_page(page); |
1727 | if (ocfs2_meta_lock(inode, handle, ret_bh, ex) == 0) | 1719 | if (ocfs2_meta_lock(inode, ret_bh, ex) == 0) |
1728 | ocfs2_meta_unlock(inode, ex); | 1720 | ocfs2_meta_unlock(inode, ex); |
1729 | ret = AOP_TRUNCATED_PAGE; | 1721 | ret = AOP_TRUNCATED_PAGE; |
1730 | } | 1722 | } |
@@ -1732,6 +1724,44 @@ int ocfs2_meta_lock_with_page(struct inode *inode, | |||
1732 | return ret; | 1724 | return ret; |
1733 | } | 1725 | } |
1734 | 1726 | ||
1727 | int ocfs2_meta_lock_atime(struct inode *inode, | ||
1728 | struct vfsmount *vfsmnt, | ||
1729 | int *level) | ||
1730 | { | ||
1731 | int ret; | ||
1732 | |||
1733 | mlog_entry_void(); | ||
1734 | ret = ocfs2_meta_lock(inode, NULL, 0); | ||
1735 | if (ret < 0) { | ||
1736 | mlog_errno(ret); | ||
1737 | return ret; | ||
1738 | } | ||
1739 | |||
1740 | /* | ||
1741 | * If we should update atime, we will get EX lock, | ||
1742 | * otherwise we just get PR lock. | ||
1743 | */ | ||
1744 | if (ocfs2_should_update_atime(inode, vfsmnt)) { | ||
1745 | struct buffer_head *bh = NULL; | ||
1746 | |||
1747 | ocfs2_meta_unlock(inode, 0); | ||
1748 | ret = ocfs2_meta_lock(inode, &bh, 1); | ||
1749 | if (ret < 0) { | ||
1750 | mlog_errno(ret); | ||
1751 | return ret; | ||
1752 | } | ||
1753 | *level = 1; | ||
1754 | if (ocfs2_should_update_atime(inode, vfsmnt)) | ||
1755 | ocfs2_update_inode_atime(inode, bh); | ||
1756 | if (bh) | ||
1757 | brelse(bh); | ||
1758 | } else | ||
1759 | *level = 0; | ||
1760 | |||
1761 | mlog_exit(ret); | ||
1762 | return ret; | ||
1763 | } | ||
1764 | |||
1735 | void ocfs2_meta_unlock(struct inode *inode, | 1765 | void ocfs2_meta_unlock(struct inode *inode, |
1736 | int ex) | 1766 | int ex) |
1737 | { | 1767 | { |
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h index 4a2769387229..c343fca68cf1 100644 --- a/fs/ocfs2/dlmglue.h +++ b/fs/ocfs2/dlmglue.h | |||
@@ -68,8 +68,6 @@ void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl, | |||
68 | u64 parent, struct inode *inode); | 68 | u64 parent, struct inode *inode); |
69 | void ocfs2_lock_res_free(struct ocfs2_lock_res *res); | 69 | void ocfs2_lock_res_free(struct ocfs2_lock_res *res); |
70 | int ocfs2_create_new_inode_locks(struct inode *inode); | 70 | int ocfs2_create_new_inode_locks(struct inode *inode); |
71 | int ocfs2_create_new_lock(struct ocfs2_super *osb, | ||
72 | struct ocfs2_lock_res *lockres, int ex, int local); | ||
73 | int ocfs2_drop_inode_locks(struct inode *inode); | 71 | int ocfs2_drop_inode_locks(struct inode *inode); |
74 | int ocfs2_data_lock_full(struct inode *inode, | 72 | int ocfs2_data_lock_full(struct inode *inode, |
75 | int write, | 73 | int write, |
@@ -82,19 +80,20 @@ void ocfs2_data_unlock(struct inode *inode, | |||
82 | int write); | 80 | int write); |
83 | int ocfs2_rw_lock(struct inode *inode, int write); | 81 | int ocfs2_rw_lock(struct inode *inode, int write); |
84 | void ocfs2_rw_unlock(struct inode *inode, int write); | 82 | void ocfs2_rw_unlock(struct inode *inode, int write); |
83 | int ocfs2_meta_lock_atime(struct inode *inode, | ||
84 | struct vfsmount *vfsmnt, | ||
85 | int *level); | ||
85 | int ocfs2_meta_lock_full(struct inode *inode, | 86 | int ocfs2_meta_lock_full(struct inode *inode, |
86 | struct ocfs2_journal_handle *handle, | ||
87 | struct buffer_head **ret_bh, | 87 | struct buffer_head **ret_bh, |
88 | int ex, | 88 | int ex, |
89 | int arg_flags); | 89 | int arg_flags); |
90 | int ocfs2_meta_lock_with_page(struct inode *inode, | 90 | int ocfs2_meta_lock_with_page(struct inode *inode, |
91 | struct ocfs2_journal_handle *handle, | ||
92 | struct buffer_head **ret_bh, | 91 | struct buffer_head **ret_bh, |
93 | int ex, | 92 | int ex, |
94 | struct page *page); | 93 | struct page *page); |
95 | /* 99% of the time we don't want to supply any additional flags -- | 94 | /* 99% of the time we don't want to supply any additional flags -- |
96 | * those are for very specific cases only. */ | 95 | * those are for very specific cases only. */ |
97 | #define ocfs2_meta_lock(i, h, b, e) ocfs2_meta_lock_full(i, h, b, e, 0) | 96 | #define ocfs2_meta_lock(i, b, e) ocfs2_meta_lock_full(i, b, e, 0) |
98 | void ocfs2_meta_unlock(struct inode *inode, | 97 | void ocfs2_meta_unlock(struct inode *inode, |
99 | int ex); | 98 | int ex); |
100 | int ocfs2_super_lock(struct ocfs2_super *osb, | 99 | int ocfs2_super_lock(struct ocfs2_super *osb, |
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c index fb91089a60a7..06be6e774cf9 100644 --- a/fs/ocfs2/export.c +++ b/fs/ocfs2/export.c | |||
@@ -100,7 +100,7 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) | |||
100 | mlog(0, "find parent of directory %llu\n", | 100 | mlog(0, "find parent of directory %llu\n", |
101 | (unsigned long long)OCFS2_I(dir)->ip_blkno); | 101 | (unsigned long long)OCFS2_I(dir)->ip_blkno); |
102 | 102 | ||
103 | status = ocfs2_meta_lock(dir, NULL, NULL, 0); | 103 | status = ocfs2_meta_lock(dir, NULL, 0); |
104 | if (status < 0) { | 104 | if (status < 0) { |
105 | if (status != -ENOENT) | 105 | if (status != -ENOENT) |
106 | mlog_errno(status); | 106 | mlog_errno(status); |
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index fcd4475d1f89..80ac69f11d9f 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c | |||
@@ -61,7 +61,7 @@ struct ocfs2_em_insert_context { | |||
61 | struct ocfs2_extent_map_entry *right_ent; | 61 | struct ocfs2_extent_map_entry *right_ent; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | static kmem_cache_t *ocfs2_em_ent_cachep = NULL; | 64 | static struct kmem_cache *ocfs2_em_ent_cachep = NULL; |
65 | 65 | ||
66 | 66 | ||
67 | static struct ocfs2_extent_map_entry * | 67 | static struct ocfs2_extent_map_entry * |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 1be74c4e7814..8786b3c490aa 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
32 | #include <linux/uio.h> | 32 | #include <linux/uio.h> |
33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/pipe_fs_i.h> | ||
35 | #include <linux/mount.h> | ||
34 | 36 | ||
35 | #define MLOG_MASK_PREFIX ML_INODE | 37 | #define MLOG_MASK_PREFIX ML_INODE |
36 | #include <cluster/masklog.h> | 38 | #include <cluster/masklog.h> |
@@ -134,7 +136,58 @@ bail: | |||
134 | return (err < 0) ? -EIO : 0; | 136 | return (err < 0) ? -EIO : 0; |
135 | } | 137 | } |
136 | 138 | ||
137 | int ocfs2_set_inode_size(struct ocfs2_journal_handle *handle, | 139 | int ocfs2_should_update_atime(struct inode *inode, |
140 | struct vfsmount *vfsmnt) | ||
141 | { | ||
142 | struct timespec now; | ||
143 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
144 | |||
145 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | ||
146 | return 0; | ||
147 | |||
148 | if ((inode->i_flags & S_NOATIME) || | ||
149 | ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) | ||
150 | return 0; | ||
151 | |||
152 | if ((vfsmnt->mnt_flags & MNT_NOATIME) || | ||
153 | ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) | ||
154 | return 0; | ||
155 | |||
156 | now = CURRENT_TIME; | ||
157 | if ((now.tv_sec - inode->i_atime.tv_sec <= osb->s_atime_quantum)) | ||
158 | return 0; | ||
159 | else | ||
160 | return 1; | ||
161 | } | ||
162 | |||
163 | int ocfs2_update_inode_atime(struct inode *inode, | ||
164 | struct buffer_head *bh) | ||
165 | { | ||
166 | int ret; | ||
167 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
168 | handle_t *handle; | ||
169 | |||
170 | mlog_entry_void(); | ||
171 | |||
172 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); | ||
173 | if (handle == NULL) { | ||
174 | ret = -ENOMEM; | ||
175 | mlog_errno(ret); | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | inode->i_atime = CURRENT_TIME; | ||
180 | ret = ocfs2_mark_inode_dirty(handle, inode, bh); | ||
181 | if (ret < 0) | ||
182 | mlog_errno(ret); | ||
183 | |||
184 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | ||
185 | out: | ||
186 | mlog_exit(ret); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | int ocfs2_set_inode_size(handle_t *handle, | ||
138 | struct inode *inode, | 191 | struct inode *inode, |
139 | struct buffer_head *fe_bh, | 192 | struct buffer_head *fe_bh, |
140 | u64 new_i_size) | 193 | u64 new_i_size) |
@@ -163,10 +216,9 @@ static int ocfs2_simple_size_update(struct inode *inode, | |||
163 | { | 216 | { |
164 | int ret; | 217 | int ret; |
165 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 218 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
166 | struct ocfs2_journal_handle *handle = NULL; | 219 | handle_t *handle = NULL; |
167 | 220 | ||
168 | handle = ocfs2_start_trans(osb, NULL, | 221 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
169 | OCFS2_INODE_UPDATE_CREDITS); | ||
170 | if (handle == NULL) { | 222 | if (handle == NULL) { |
171 | ret = -ENOMEM; | 223 | ret = -ENOMEM; |
172 | mlog_errno(ret); | 224 | mlog_errno(ret); |
@@ -178,7 +230,7 @@ static int ocfs2_simple_size_update(struct inode *inode, | |||
178 | if (ret < 0) | 230 | if (ret < 0) |
179 | mlog_errno(ret); | 231 | mlog_errno(ret); |
180 | 232 | ||
181 | ocfs2_commit_trans(handle); | 233 | ocfs2_commit_trans(osb, handle); |
182 | out: | 234 | out: |
183 | return ret; | 235 | return ret; |
184 | } | 236 | } |
@@ -189,14 +241,14 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb, | |||
189 | u64 new_i_size) | 241 | u64 new_i_size) |
190 | { | 242 | { |
191 | int status; | 243 | int status; |
192 | struct ocfs2_journal_handle *handle; | 244 | handle_t *handle; |
193 | 245 | ||
194 | mlog_entry_void(); | 246 | mlog_entry_void(); |
195 | 247 | ||
196 | /* TODO: This needs to actually orphan the inode in this | 248 | /* TODO: This needs to actually orphan the inode in this |
197 | * transaction. */ | 249 | * transaction. */ |
198 | 250 | ||
199 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 251 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
200 | if (IS_ERR(handle)) { | 252 | if (IS_ERR(handle)) { |
201 | status = PTR_ERR(handle); | 253 | status = PTR_ERR(handle); |
202 | mlog_errno(status); | 254 | mlog_errno(status); |
@@ -207,7 +259,7 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb, | |||
207 | if (status < 0) | 259 | if (status < 0) |
208 | mlog_errno(status); | 260 | mlog_errno(status); |
209 | 261 | ||
210 | ocfs2_commit_trans(handle); | 262 | ocfs2_commit_trans(osb, handle); |
211 | out: | 263 | out: |
212 | mlog_exit(status); | 264 | mlog_exit(status); |
213 | return status; | 265 | return status; |
@@ -328,7 +380,7 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
328 | struct inode *inode, | 380 | struct inode *inode, |
329 | u32 clusters_to_add, | 381 | u32 clusters_to_add, |
330 | struct buffer_head *fe_bh, | 382 | struct buffer_head *fe_bh, |
331 | struct ocfs2_journal_handle *handle, | 383 | handle_t *handle, |
332 | struct ocfs2_alloc_context *data_ac, | 384 | struct ocfs2_alloc_context *data_ac, |
333 | struct ocfs2_alloc_context *meta_ac, | 385 | struct ocfs2_alloc_context *meta_ac, |
334 | enum ocfs2_alloc_restarted *reason_ret) | 386 | enum ocfs2_alloc_restarted *reason_ret) |
@@ -433,7 +485,7 @@ static int ocfs2_extend_allocation(struct inode *inode, | |||
433 | u32 prev_clusters; | 485 | u32 prev_clusters; |
434 | struct buffer_head *bh = NULL; | 486 | struct buffer_head *bh = NULL; |
435 | struct ocfs2_dinode *fe = NULL; | 487 | struct ocfs2_dinode *fe = NULL; |
436 | struct ocfs2_journal_handle *handle = NULL; | 488 | handle_t *handle = NULL; |
437 | struct ocfs2_alloc_context *data_ac = NULL; | 489 | struct ocfs2_alloc_context *data_ac = NULL; |
438 | struct ocfs2_alloc_context *meta_ac = NULL; | 490 | struct ocfs2_alloc_context *meta_ac = NULL; |
439 | enum ocfs2_alloc_restarted why; | 491 | enum ocfs2_alloc_restarted why; |
@@ -463,13 +515,6 @@ restart_all: | |||
463 | (unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode), | 515 | (unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode), |
464 | fe->i_clusters, clusters_to_add); | 516 | fe->i_clusters, clusters_to_add); |
465 | 517 | ||
466 | handle = ocfs2_alloc_handle(osb); | ||
467 | if (handle == NULL) { | ||
468 | status = -ENOMEM; | ||
469 | mlog_errno(status); | ||
470 | goto leave; | ||
471 | } | ||
472 | |||
473 | num_free_extents = ocfs2_num_free_extents(osb, | 518 | num_free_extents = ocfs2_num_free_extents(osb, |
474 | inode, | 519 | inode, |
475 | fe); | 520 | fe); |
@@ -480,10 +525,7 @@ restart_all: | |||
480 | } | 525 | } |
481 | 526 | ||
482 | if (!num_free_extents) { | 527 | if (!num_free_extents) { |
483 | status = ocfs2_reserve_new_metadata(osb, | 528 | status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac); |
484 | handle, | ||
485 | fe, | ||
486 | &meta_ac); | ||
487 | if (status < 0) { | 529 | if (status < 0) { |
488 | if (status != -ENOSPC) | 530 | if (status != -ENOSPC) |
489 | mlog_errno(status); | 531 | mlog_errno(status); |
@@ -491,10 +533,7 @@ restart_all: | |||
491 | } | 533 | } |
492 | } | 534 | } |
493 | 535 | ||
494 | status = ocfs2_reserve_clusters(osb, | 536 | status = ocfs2_reserve_clusters(osb, clusters_to_add, &data_ac); |
495 | handle, | ||
496 | clusters_to_add, | ||
497 | &data_ac); | ||
498 | if (status < 0) { | 537 | if (status < 0) { |
499 | if (status != -ENOSPC) | 538 | if (status != -ENOSPC) |
500 | mlog_errno(status); | 539 | mlog_errno(status); |
@@ -509,7 +548,7 @@ restart_all: | |||
509 | drop_alloc_sem = 1; | 548 | drop_alloc_sem = 1; |
510 | 549 | ||
511 | credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add); | 550 | credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add); |
512 | handle = ocfs2_start_trans(osb, handle, credits); | 551 | handle = ocfs2_start_trans(osb, credits); |
513 | if (IS_ERR(handle)) { | 552 | if (IS_ERR(handle)) { |
514 | status = PTR_ERR(handle); | 553 | status = PTR_ERR(handle); |
515 | handle = NULL; | 554 | handle = NULL; |
@@ -589,7 +628,7 @@ leave: | |||
589 | drop_alloc_sem = 0; | 628 | drop_alloc_sem = 0; |
590 | } | 629 | } |
591 | if (handle) { | 630 | if (handle) { |
592 | ocfs2_commit_trans(handle); | 631 | ocfs2_commit_trans(osb, handle); |
593 | handle = NULL; | 632 | handle = NULL; |
594 | } | 633 | } |
595 | if (data_ac) { | 634 | if (data_ac) { |
@@ -624,7 +663,7 @@ static int ocfs2_write_zero_page(struct inode *inode, | |||
624 | struct page *page; | 663 | struct page *page; |
625 | unsigned long index; | 664 | unsigned long index; |
626 | unsigned int offset; | 665 | unsigned int offset; |
627 | struct ocfs2_journal_handle *handle = NULL; | 666 | handle_t *handle = NULL; |
628 | int ret; | 667 | int ret; |
629 | 668 | ||
630 | offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ | 669 | offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ |
@@ -668,7 +707,7 @@ static int ocfs2_write_zero_page(struct inode *inode, | |||
668 | ret = 0; | 707 | ret = 0; |
669 | 708 | ||
670 | if (handle) | 709 | if (handle) |
671 | ocfs2_commit_trans(handle); | 710 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
672 | out_unlock: | 711 | out_unlock: |
673 | unlock_page(page); | 712 | unlock_page(page); |
674 | page_cache_release(page); | 713 | page_cache_release(page); |
@@ -789,7 +828,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
789 | struct super_block *sb = inode->i_sb; | 828 | struct super_block *sb = inode->i_sb; |
790 | struct ocfs2_super *osb = OCFS2_SB(sb); | 829 | struct ocfs2_super *osb = OCFS2_SB(sb); |
791 | struct buffer_head *bh = NULL; | 830 | struct buffer_head *bh = NULL; |
792 | struct ocfs2_journal_handle *handle = NULL; | 831 | handle_t *handle = NULL; |
793 | 832 | ||
794 | mlog_entry("(0x%p, '%.*s')\n", dentry, | 833 | mlog_entry("(0x%p, '%.*s')\n", dentry, |
795 | dentry->d_name.len, dentry->d_name.name); | 834 | dentry->d_name.len, dentry->d_name.name); |
@@ -825,7 +864,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
825 | } | 864 | } |
826 | } | 865 | } |
827 | 866 | ||
828 | status = ocfs2_meta_lock(inode, NULL, &bh, 1); | 867 | status = ocfs2_meta_lock(inode, &bh, 1); |
829 | if (status < 0) { | 868 | if (status < 0) { |
830 | if (status != -ENOENT) | 869 | if (status != -ENOENT) |
831 | mlog_errno(status); | 870 | mlog_errno(status); |
@@ -845,7 +884,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
845 | } | 884 | } |
846 | } | 885 | } |
847 | 886 | ||
848 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 887 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
849 | if (IS_ERR(handle)) { | 888 | if (IS_ERR(handle)) { |
850 | status = PTR_ERR(handle); | 889 | status = PTR_ERR(handle); |
851 | mlog_errno(status); | 890 | mlog_errno(status); |
@@ -863,7 +902,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
863 | mlog_errno(status); | 902 | mlog_errno(status); |
864 | 903 | ||
865 | bail_commit: | 904 | bail_commit: |
866 | ocfs2_commit_trans(handle); | 905 | ocfs2_commit_trans(osb, handle); |
867 | bail_unlock: | 906 | bail_unlock: |
868 | ocfs2_meta_unlock(inode, 1); | 907 | ocfs2_meta_unlock(inode, 1); |
869 | bail_unlock_rw: | 908 | bail_unlock_rw: |
@@ -906,19 +945,41 @@ bail: | |||
906 | return err; | 945 | return err; |
907 | } | 946 | } |
908 | 947 | ||
948 | int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd) | ||
949 | { | ||
950 | int ret; | ||
951 | |||
952 | mlog_entry_void(); | ||
953 | |||
954 | ret = ocfs2_meta_lock(inode, NULL, 0); | ||
955 | if (ret) { | ||
956 | mlog_errno(ret); | ||
957 | goto out; | ||
958 | } | ||
959 | |||
960 | ret = generic_permission(inode, mask, NULL); | ||
961 | if (ret) | ||
962 | mlog_errno(ret); | ||
963 | |||
964 | ocfs2_meta_unlock(inode, 0); | ||
965 | out: | ||
966 | mlog_exit(ret); | ||
967 | return ret; | ||
968 | } | ||
969 | |||
909 | static int ocfs2_write_remove_suid(struct inode *inode) | 970 | static int ocfs2_write_remove_suid(struct inode *inode) |
910 | { | 971 | { |
911 | int ret; | 972 | int ret; |
912 | struct buffer_head *bh = NULL; | 973 | struct buffer_head *bh = NULL; |
913 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 974 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
914 | struct ocfs2_journal_handle *handle; | 975 | handle_t *handle; |
915 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 976 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
916 | struct ocfs2_dinode *di; | 977 | struct ocfs2_dinode *di; |
917 | 978 | ||
918 | mlog_entry("(Inode %llu, mode 0%o)\n", | 979 | mlog_entry("(Inode %llu, mode 0%o)\n", |
919 | (unsigned long long)oi->ip_blkno, inode->i_mode); | 980 | (unsigned long long)oi->ip_blkno, inode->i_mode); |
920 | 981 | ||
921 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 982 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
922 | if (handle == NULL) { | 983 | if (handle == NULL) { |
923 | ret = -ENOMEM; | 984 | ret = -ENOMEM; |
924 | mlog_errno(ret); | 985 | mlog_errno(ret); |
@@ -951,75 +1012,29 @@ static int ocfs2_write_remove_suid(struct inode *inode) | |||
951 | out_bh: | 1012 | out_bh: |
952 | brelse(bh); | 1013 | brelse(bh); |
953 | out_trans: | 1014 | out_trans: |
954 | ocfs2_commit_trans(handle); | 1015 | ocfs2_commit_trans(osb, handle); |
955 | out: | 1016 | out: |
956 | mlog_exit(ret); | 1017 | mlog_exit(ret); |
957 | return ret; | 1018 | return ret; |
958 | } | 1019 | } |
959 | 1020 | ||
960 | static inline int ocfs2_write_should_remove_suid(struct inode *inode) | 1021 | static int ocfs2_prepare_inode_for_write(struct dentry *dentry, |
961 | { | 1022 | loff_t *ppos, |
962 | mode_t mode = inode->i_mode; | 1023 | size_t count, |
963 | 1024 | int appending) | |
964 | if (!capable(CAP_FSETID)) { | ||
965 | if (unlikely(mode & S_ISUID)) | ||
966 | return 1; | ||
967 | |||
968 | if (unlikely((mode & S_ISGID) && (mode & S_IXGRP))) | ||
969 | return 1; | ||
970 | } | ||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | ||
975 | const struct iovec *iov, | ||
976 | unsigned long nr_segs, | ||
977 | loff_t pos) | ||
978 | { | 1025 | { |
979 | int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0; | 1026 | int ret = 0, meta_level = appending; |
1027 | struct inode *inode = dentry->d_inode; | ||
980 | u32 clusters; | 1028 | u32 clusters; |
981 | struct file *filp = iocb->ki_filp; | ||
982 | struct inode *inode = filp->f_dentry->d_inode; | ||
983 | loff_t newsize, saved_pos; | 1029 | loff_t newsize, saved_pos; |
984 | 1030 | ||
985 | mlog_entry("(0x%p, %u, '%.*s')\n", filp, | ||
986 | (unsigned int)nr_segs, | ||
987 | filp->f_dentry->d_name.len, | ||
988 | filp->f_dentry->d_name.name); | ||
989 | |||
990 | /* happy write of zero bytes */ | ||
991 | if (iocb->ki_left == 0) | ||
992 | return 0; | ||
993 | |||
994 | if (!inode) { | ||
995 | mlog(0, "bad inode\n"); | ||
996 | return -EIO; | ||
997 | } | ||
998 | |||
999 | mutex_lock(&inode->i_mutex); | ||
1000 | /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ | ||
1001 | if (filp->f_flags & O_DIRECT) { | ||
1002 | have_alloc_sem = 1; | ||
1003 | down_read(&inode->i_alloc_sem); | ||
1004 | } | ||
1005 | |||
1006 | /* concurrent O_DIRECT writes are allowed */ | ||
1007 | rw_level = (filp->f_flags & O_DIRECT) ? 0 : 1; | ||
1008 | ret = ocfs2_rw_lock(inode, rw_level); | ||
1009 | if (ret < 0) { | ||
1010 | rw_level = -1; | ||
1011 | mlog_errno(ret); | ||
1012 | goto out; | ||
1013 | } | ||
1014 | |||
1015 | /* | 1031 | /* |
1016 | * We sample i_size under a read level meta lock to see if our write | 1032 | * We sample i_size under a read level meta lock to see if our write |
1017 | * is extending the file, if it is we back off and get a write level | 1033 | * is extending the file, if it is we back off and get a write level |
1018 | * meta lock. | 1034 | * meta lock. |
1019 | */ | 1035 | */ |
1020 | meta_level = (filp->f_flags & O_APPEND) ? 1 : 0; | ||
1021 | for(;;) { | 1036 | for(;;) { |
1022 | ret = ocfs2_meta_lock(inode, NULL, NULL, meta_level); | 1037 | ret = ocfs2_meta_lock(inode, NULL, meta_level); |
1023 | if (ret < 0) { | 1038 | if (ret < 0) { |
1024 | meta_level = -1; | 1039 | meta_level = -1; |
1025 | mlog_errno(ret); | 1040 | mlog_errno(ret); |
@@ -1035,7 +1050,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1035 | * inode. There's also the dinode i_size state which | 1050 | * inode. There's also the dinode i_size state which |
1036 | * can be lost via setattr during extending writes (we | 1051 | * can be lost via setattr during extending writes (we |
1037 | * set inode->i_size at the end of a write. */ | 1052 | * set inode->i_size at the end of a write. */ |
1038 | if (ocfs2_write_should_remove_suid(inode)) { | 1053 | if (should_remove_suid(dentry)) { |
1039 | if (meta_level == 0) { | 1054 | if (meta_level == 0) { |
1040 | ocfs2_meta_unlock(inode, meta_level); | 1055 | ocfs2_meta_unlock(inode, meta_level); |
1041 | meta_level = 1; | 1056 | meta_level = 1; |
@@ -1045,19 +1060,19 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1045 | ret = ocfs2_write_remove_suid(inode); | 1060 | ret = ocfs2_write_remove_suid(inode); |
1046 | if (ret < 0) { | 1061 | if (ret < 0) { |
1047 | mlog_errno(ret); | 1062 | mlog_errno(ret); |
1048 | goto out; | 1063 | goto out_unlock; |
1049 | } | 1064 | } |
1050 | } | 1065 | } |
1051 | 1066 | ||
1052 | /* work on a copy of ppos until we're sure that we won't have | 1067 | /* work on a copy of ppos until we're sure that we won't have |
1053 | * to recalculate it due to relocking. */ | 1068 | * to recalculate it due to relocking. */ |
1054 | if (filp->f_flags & O_APPEND) { | 1069 | if (appending) { |
1055 | saved_pos = i_size_read(inode); | 1070 | saved_pos = i_size_read(inode); |
1056 | mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos); | 1071 | mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos); |
1057 | } else { | 1072 | } else { |
1058 | saved_pos = iocb->ki_pos; | 1073 | saved_pos = *ppos; |
1059 | } | 1074 | } |
1060 | newsize = iocb->ki_left + saved_pos; | 1075 | newsize = count + saved_pos; |
1061 | 1076 | ||
1062 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", | 1077 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", |
1063 | (long long) saved_pos, (long long) newsize, | 1078 | (long long) saved_pos, (long long) newsize, |
@@ -1090,19 +1105,66 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1090 | if (!clusters) | 1105 | if (!clusters) |
1091 | break; | 1106 | break; |
1092 | 1107 | ||
1093 | ret = ocfs2_extend_file(inode, NULL, newsize, iocb->ki_left); | 1108 | ret = ocfs2_extend_file(inode, NULL, newsize, count); |
1094 | if (ret < 0) { | 1109 | if (ret < 0) { |
1095 | if (ret != -ENOSPC) | 1110 | if (ret != -ENOSPC) |
1096 | mlog_errno(ret); | 1111 | mlog_errno(ret); |
1097 | goto out; | 1112 | goto out_unlock; |
1098 | } | 1113 | } |
1099 | break; | 1114 | break; |
1100 | } | 1115 | } |
1101 | 1116 | ||
1102 | /* ok, we're done with i_size and alloc work */ | 1117 | if (appending) |
1103 | iocb->ki_pos = saved_pos; | 1118 | *ppos = saved_pos; |
1119 | |||
1120 | out_unlock: | ||
1104 | ocfs2_meta_unlock(inode, meta_level); | 1121 | ocfs2_meta_unlock(inode, meta_level); |
1105 | meta_level = -1; | 1122 | |
1123 | out: | ||
1124 | return ret; | ||
1125 | } | ||
1126 | |||
1127 | static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | ||
1128 | const struct iovec *iov, | ||
1129 | unsigned long nr_segs, | ||
1130 | loff_t pos) | ||
1131 | { | ||
1132 | int ret, rw_level, have_alloc_sem = 0; | ||
1133 | struct file *filp = iocb->ki_filp; | ||
1134 | struct inode *inode = filp->f_dentry->d_inode; | ||
1135 | int appending = filp->f_flags & O_APPEND ? 1 : 0; | ||
1136 | |||
1137 | mlog_entry("(0x%p, %u, '%.*s')\n", filp, | ||
1138 | (unsigned int)nr_segs, | ||
1139 | filp->f_dentry->d_name.len, | ||
1140 | filp->f_dentry->d_name.name); | ||
1141 | |||
1142 | /* happy write of zero bytes */ | ||
1143 | if (iocb->ki_left == 0) | ||
1144 | return 0; | ||
1145 | |||
1146 | mutex_lock(&inode->i_mutex); | ||
1147 | /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ | ||
1148 | if (filp->f_flags & O_DIRECT) { | ||
1149 | have_alloc_sem = 1; | ||
1150 | down_read(&inode->i_alloc_sem); | ||
1151 | } | ||
1152 | |||
1153 | /* concurrent O_DIRECT writes are allowed */ | ||
1154 | rw_level = (filp->f_flags & O_DIRECT) ? 0 : 1; | ||
1155 | ret = ocfs2_rw_lock(inode, rw_level); | ||
1156 | if (ret < 0) { | ||
1157 | rw_level = -1; | ||
1158 | mlog_errno(ret); | ||
1159 | goto out; | ||
1160 | } | ||
1161 | |||
1162 | ret = ocfs2_prepare_inode_for_write(filp->f_dentry, &iocb->ki_pos, | ||
1163 | iocb->ki_left, appending); | ||
1164 | if (ret < 0) { | ||
1165 | mlog_errno(ret); | ||
1166 | goto out; | ||
1167 | } | ||
1106 | 1168 | ||
1107 | /* communicate with ocfs2_dio_end_io */ | 1169 | /* communicate with ocfs2_dio_end_io */ |
1108 | ocfs2_iocb_set_rw_locked(iocb); | 1170 | ocfs2_iocb_set_rw_locked(iocb); |
@@ -1128,8 +1190,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
1128 | } | 1190 | } |
1129 | 1191 | ||
1130 | out: | 1192 | out: |
1131 | if (meta_level != -1) | ||
1132 | ocfs2_meta_unlock(inode, meta_level); | ||
1133 | if (have_alloc_sem) | 1193 | if (have_alloc_sem) |
1134 | up_read(&inode->i_alloc_sem); | 1194 | up_read(&inode->i_alloc_sem); |
1135 | if (rw_level != -1) | 1195 | if (rw_level != -1) |
@@ -1140,12 +1200,83 @@ out: | |||
1140 | return ret; | 1200 | return ret; |
1141 | } | 1201 | } |
1142 | 1202 | ||
1203 | static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | ||
1204 | struct file *out, | ||
1205 | loff_t *ppos, | ||
1206 | size_t len, | ||
1207 | unsigned int flags) | ||
1208 | { | ||
1209 | int ret; | ||
1210 | struct inode *inode = out->f_dentry->d_inode; | ||
1211 | |||
1212 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", out, pipe, | ||
1213 | (unsigned int)len, | ||
1214 | out->f_dentry->d_name.len, | ||
1215 | out->f_dentry->d_name.name); | ||
1216 | |||
1217 | inode_double_lock(inode, pipe->inode); | ||
1218 | |||
1219 | ret = ocfs2_rw_lock(inode, 1); | ||
1220 | if (ret < 0) { | ||
1221 | mlog_errno(ret); | ||
1222 | goto out; | ||
1223 | } | ||
1224 | |||
1225 | ret = ocfs2_prepare_inode_for_write(out->f_dentry, ppos, len, 0); | ||
1226 | if (ret < 0) { | ||
1227 | mlog_errno(ret); | ||
1228 | goto out_unlock; | ||
1229 | } | ||
1230 | |||
1231 | /* ok, we're done with i_size and alloc work */ | ||
1232 | ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags); | ||
1233 | |||
1234 | out_unlock: | ||
1235 | ocfs2_rw_unlock(inode, 1); | ||
1236 | out: | ||
1237 | inode_double_unlock(inode, pipe->inode); | ||
1238 | |||
1239 | mlog_exit(ret); | ||
1240 | return ret; | ||
1241 | } | ||
1242 | |||
1243 | static ssize_t ocfs2_file_splice_read(struct file *in, | ||
1244 | loff_t *ppos, | ||
1245 | struct pipe_inode_info *pipe, | ||
1246 | size_t len, | ||
1247 | unsigned int flags) | ||
1248 | { | ||
1249 | int ret = 0; | ||
1250 | struct inode *inode = in->f_dentry->d_inode; | ||
1251 | |||
1252 | mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", in, pipe, | ||
1253 | (unsigned int)len, | ||
1254 | in->f_dentry->d_name.len, | ||
1255 | in->f_dentry->d_name.name); | ||
1256 | |||
1257 | /* | ||
1258 | * See the comment in ocfs2_file_aio_read() | ||
1259 | */ | ||
1260 | ret = ocfs2_meta_lock(inode, NULL, 0); | ||
1261 | if (ret < 0) { | ||
1262 | mlog_errno(ret); | ||
1263 | goto bail; | ||
1264 | } | ||
1265 | ocfs2_meta_unlock(inode, 0); | ||
1266 | |||
1267 | ret = generic_file_splice_read(in, ppos, pipe, len, flags); | ||
1268 | |||
1269 | bail: | ||
1270 | mlog_exit(ret); | ||
1271 | return ret; | ||
1272 | } | ||
1273 | |||
1143 | static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | 1274 | static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, |
1144 | const struct iovec *iov, | 1275 | const struct iovec *iov, |
1145 | unsigned long nr_segs, | 1276 | unsigned long nr_segs, |
1146 | loff_t pos) | 1277 | loff_t pos) |
1147 | { | 1278 | { |
1148 | int ret = 0, rw_level = -1, have_alloc_sem = 0; | 1279 | int ret = 0, rw_level = -1, have_alloc_sem = 0, lock_level = 0; |
1149 | struct file *filp = iocb->ki_filp; | 1280 | struct file *filp = iocb->ki_filp; |
1150 | struct inode *inode = filp->f_dentry->d_inode; | 1281 | struct inode *inode = filp->f_dentry->d_inode; |
1151 | 1282 | ||
@@ -1187,12 +1318,12 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
1187 | * like i_size. This allows the checks down below | 1318 | * like i_size. This allows the checks down below |
1188 | * generic_file_aio_read() a chance of actually working. | 1319 | * generic_file_aio_read() a chance of actually working. |
1189 | */ | 1320 | */ |
1190 | ret = ocfs2_meta_lock(inode, NULL, NULL, 0); | 1321 | ret = ocfs2_meta_lock_atime(inode, filp->f_vfsmnt, &lock_level); |
1191 | if (ret < 0) { | 1322 | if (ret < 0) { |
1192 | mlog_errno(ret); | 1323 | mlog_errno(ret); |
1193 | goto bail; | 1324 | goto bail; |
1194 | } | 1325 | } |
1195 | ocfs2_meta_unlock(inode, 0); | 1326 | ocfs2_meta_unlock(inode, lock_level); |
1196 | 1327 | ||
1197 | ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); | 1328 | ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); |
1198 | if (ret == -EINVAL) | 1329 | if (ret == -EINVAL) |
@@ -1220,11 +1351,13 @@ bail: | |||
1220 | struct inode_operations ocfs2_file_iops = { | 1351 | struct inode_operations ocfs2_file_iops = { |
1221 | .setattr = ocfs2_setattr, | 1352 | .setattr = ocfs2_setattr, |
1222 | .getattr = ocfs2_getattr, | 1353 | .getattr = ocfs2_getattr, |
1354 | .permission = ocfs2_permission, | ||
1223 | }; | 1355 | }; |
1224 | 1356 | ||
1225 | struct inode_operations ocfs2_special_file_iops = { | 1357 | struct inode_operations ocfs2_special_file_iops = { |
1226 | .setattr = ocfs2_setattr, | 1358 | .setattr = ocfs2_setattr, |
1227 | .getattr = ocfs2_getattr, | 1359 | .getattr = ocfs2_getattr, |
1360 | .permission = ocfs2_permission, | ||
1228 | }; | 1361 | }; |
1229 | 1362 | ||
1230 | const struct file_operations ocfs2_fops = { | 1363 | const struct file_operations ocfs2_fops = { |
@@ -1238,6 +1371,8 @@ const struct file_operations ocfs2_fops = { | |||
1238 | .aio_read = ocfs2_file_aio_read, | 1371 | .aio_read = ocfs2_file_aio_read, |
1239 | .aio_write = ocfs2_file_aio_write, | 1372 | .aio_write = ocfs2_file_aio_write, |
1240 | .ioctl = ocfs2_ioctl, | 1373 | .ioctl = ocfs2_ioctl, |
1374 | .splice_read = ocfs2_file_splice_read, | ||
1375 | .splice_write = ocfs2_file_splice_write, | ||
1241 | }; | 1376 | }; |
1242 | 1377 | ||
1243 | const struct file_operations ocfs2_dops = { | 1378 | const struct file_operations ocfs2_dops = { |
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h index 740c9e7ca599..601a453f18a8 100644 --- a/fs/ocfs2/file.h +++ b/fs/ocfs2/file.h | |||
@@ -41,17 +41,24 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, | |||
41 | struct inode *inode, | 41 | struct inode *inode, |
42 | u32 clusters_to_add, | 42 | u32 clusters_to_add, |
43 | struct buffer_head *fe_bh, | 43 | struct buffer_head *fe_bh, |
44 | struct ocfs2_journal_handle *handle, | 44 | handle_t *handle, |
45 | struct ocfs2_alloc_context *data_ac, | 45 | struct ocfs2_alloc_context *data_ac, |
46 | struct ocfs2_alloc_context *meta_ac, | 46 | struct ocfs2_alloc_context *meta_ac, |
47 | enum ocfs2_alloc_restarted *reason); | 47 | enum ocfs2_alloc_restarted *reason); |
48 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); | 48 | int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); |
49 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, | 49 | int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, |
50 | struct kstat *stat); | 50 | struct kstat *stat); |
51 | int ocfs2_permission(struct inode *inode, int mask, | ||
52 | struct nameidata *nd); | ||
51 | 53 | ||
52 | int ocfs2_set_inode_size(struct ocfs2_journal_handle *handle, | 54 | int ocfs2_set_inode_size(handle_t *handle, |
53 | struct inode *inode, | 55 | struct inode *inode, |
54 | struct buffer_head *fe_bh, | 56 | struct buffer_head *fe_bh, |
55 | u64 new_i_size); | 57 | u64 new_i_size); |
56 | 58 | ||
59 | int ocfs2_should_update_atime(struct inode *inode, | ||
60 | struct vfsmount *vfsmnt); | ||
61 | int ocfs2_update_inode_atime(struct inode *inode, | ||
62 | struct buffer_head *bh); | ||
63 | |||
57 | #endif /* OCFS2_FILE_H */ | 64 | #endif /* OCFS2_FILE_H */ |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index 16e8e74dc966..42e361f3054f 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
@@ -360,7 +360,6 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, | |||
360 | inode); | 360 | inode); |
361 | 361 | ||
362 | ocfs2_set_inode_flags(inode); | 362 | ocfs2_set_inode_flags(inode); |
363 | inode->i_flags |= S_NOATIME; | ||
364 | 363 | ||
365 | status = 0; | 364 | status = 0; |
366 | bail: | 365 | bail: |
@@ -441,7 +440,7 @@ static int ocfs2_read_locked_inode(struct inode *inode, | |||
441 | generation, inode); | 440 | generation, inode); |
442 | 441 | ||
443 | if (can_lock) { | 442 | if (can_lock) { |
444 | status = ocfs2_meta_lock(inode, NULL, NULL, 0); | 443 | status = ocfs2_meta_lock(inode, NULL, 0); |
445 | if (status) { | 444 | if (status) { |
446 | make_bad_inode(inode); | 445 | make_bad_inode(inode); |
447 | mlog_errno(status); | 446 | mlog_errno(status); |
@@ -512,7 +511,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
512 | struct buffer_head *fe_bh) | 511 | struct buffer_head *fe_bh) |
513 | { | 512 | { |
514 | int status = 0; | 513 | int status = 0; |
515 | struct ocfs2_journal_handle *handle = NULL; | 514 | handle_t *handle = NULL; |
516 | struct ocfs2_truncate_context *tc = NULL; | 515 | struct ocfs2_truncate_context *tc = NULL; |
517 | struct ocfs2_dinode *fe; | 516 | struct ocfs2_dinode *fe; |
518 | 517 | ||
@@ -524,7 +523,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
524 | if (!fe->i_clusters) | 523 | if (!fe->i_clusters) |
525 | goto bail; | 524 | goto bail; |
526 | 525 | ||
527 | handle = ocfs2_start_trans(osb, handle, OCFS2_INODE_UPDATE_CREDITS); | 526 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
528 | if (IS_ERR(handle)) { | 527 | if (IS_ERR(handle)) { |
529 | status = PTR_ERR(handle); | 528 | status = PTR_ERR(handle); |
530 | handle = NULL; | 529 | handle = NULL; |
@@ -538,7 +537,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
538 | goto bail; | 537 | goto bail; |
539 | } | 538 | } |
540 | 539 | ||
541 | ocfs2_commit_trans(handle); | 540 | ocfs2_commit_trans(osb, handle); |
542 | handle = NULL; | 541 | handle = NULL; |
543 | 542 | ||
544 | status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); | 543 | status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); |
@@ -554,7 +553,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, | |||
554 | } | 553 | } |
555 | bail: | 554 | bail: |
556 | if (handle) | 555 | if (handle) |
557 | ocfs2_commit_trans(handle); | 556 | ocfs2_commit_trans(osb, handle); |
558 | 557 | ||
559 | mlog_exit(status); | 558 | mlog_exit(status); |
560 | return status; | 559 | return status; |
@@ -568,7 +567,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
568 | int status; | 567 | int status; |
569 | struct inode *inode_alloc_inode = NULL; | 568 | struct inode *inode_alloc_inode = NULL; |
570 | struct buffer_head *inode_alloc_bh = NULL; | 569 | struct buffer_head *inode_alloc_bh = NULL; |
571 | struct ocfs2_journal_handle *handle; | 570 | handle_t *handle; |
572 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 571 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
573 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; | 572 | struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; |
574 | 573 | ||
@@ -582,7 +581,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
582 | } | 581 | } |
583 | 582 | ||
584 | mutex_lock(&inode_alloc_inode->i_mutex); | 583 | mutex_lock(&inode_alloc_inode->i_mutex); |
585 | status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1); | 584 | status = ocfs2_meta_lock(inode_alloc_inode, &inode_alloc_bh, 1); |
586 | if (status < 0) { | 585 | if (status < 0) { |
587 | mutex_unlock(&inode_alloc_inode->i_mutex); | 586 | mutex_unlock(&inode_alloc_inode->i_mutex); |
588 | 587 | ||
@@ -590,7 +589,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
590 | goto bail; | 589 | goto bail; |
591 | } | 590 | } |
592 | 591 | ||
593 | handle = ocfs2_start_trans(osb, NULL, OCFS2_DELETE_INODE_CREDITS); | 592 | handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS); |
594 | if (IS_ERR(handle)) { | 593 | if (IS_ERR(handle)) { |
595 | status = PTR_ERR(handle); | 594 | status = PTR_ERR(handle); |
596 | mlog_errno(status); | 595 | mlog_errno(status); |
@@ -629,7 +628,7 @@ static int ocfs2_remove_inode(struct inode *inode, | |||
629 | mlog_errno(status); | 628 | mlog_errno(status); |
630 | 629 | ||
631 | bail_commit: | 630 | bail_commit: |
632 | ocfs2_commit_trans(handle); | 631 | ocfs2_commit_trans(osb, handle); |
633 | bail_unlock: | 632 | bail_unlock: |
634 | ocfs2_meta_unlock(inode_alloc_inode, 1); | 633 | ocfs2_meta_unlock(inode_alloc_inode, 1); |
635 | mutex_unlock(&inode_alloc_inode->i_mutex); | 634 | mutex_unlock(&inode_alloc_inode->i_mutex); |
@@ -705,7 +704,7 @@ static int ocfs2_wipe_inode(struct inode *inode, | |||
705 | * delete_inode operation. We do this now to avoid races with | 704 | * delete_inode operation. We do this now to avoid races with |
706 | * recovery completion on other nodes. */ | 705 | * recovery completion on other nodes. */ |
707 | mutex_lock(&orphan_dir_inode->i_mutex); | 706 | mutex_lock(&orphan_dir_inode->i_mutex); |
708 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1); | 707 | status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1); |
709 | if (status < 0) { | 708 | if (status < 0) { |
710 | mutex_unlock(&orphan_dir_inode->i_mutex); | 709 | mutex_unlock(&orphan_dir_inode->i_mutex); |
711 | 710 | ||
@@ -933,7 +932,7 @@ void ocfs2_delete_inode(struct inode *inode) | |||
933 | * allocation lock here as it won't be needed - nobody will | 932 | * allocation lock here as it won't be needed - nobody will |
934 | * have the file open. | 933 | * have the file open. |
935 | */ | 934 | */ |
936 | status = ocfs2_meta_lock(inode, NULL, &di_bh, 1); | 935 | status = ocfs2_meta_lock(inode, &di_bh, 1); |
937 | if (status < 0) { | 936 | if (status < 0) { |
938 | if (status != -ENOENT) | 937 | if (status != -ENOENT) |
939 | mlog_errno(status); | 938 | mlog_errno(status); |
@@ -1067,12 +1066,6 @@ void ocfs2_clear_inode(struct inode *inode) | |||
1067 | mlog_bug_on_msg(oi->ip_open_count, | 1066 | mlog_bug_on_msg(oi->ip_open_count, |
1068 | "Clear inode of %llu has open count %d\n", | 1067 | "Clear inode of %llu has open count %d\n", |
1069 | (unsigned long long)oi->ip_blkno, oi->ip_open_count); | 1068 | (unsigned long long)oi->ip_blkno, oi->ip_open_count); |
1070 | mlog_bug_on_msg(!list_empty(&oi->ip_handle_list), | ||
1071 | "Clear inode of %llu has non empty handle list\n", | ||
1072 | (unsigned long long)oi->ip_blkno); | ||
1073 | mlog_bug_on_msg(oi->ip_handle, | ||
1074 | "Clear inode of %llu has non empty handle pointer\n", | ||
1075 | (unsigned long long)oi->ip_blkno); | ||
1076 | 1069 | ||
1077 | /* Clear all other flags. */ | 1070 | /* Clear all other flags. */ |
1078 | oi->ip_flags = OCFS2_INODE_CACHE_INLINE; | 1071 | oi->ip_flags = OCFS2_INODE_CACHE_INLINE; |
@@ -1186,7 +1179,7 @@ int ocfs2_inode_revalidate(struct dentry *dentry) | |||
1186 | 1179 | ||
1187 | /* Let ocfs2_meta_lock do the work of updating our struct | 1180 | /* Let ocfs2_meta_lock do the work of updating our struct |
1188 | * inode for us. */ | 1181 | * inode for us. */ |
1189 | status = ocfs2_meta_lock(inode, NULL, NULL, 0); | 1182 | status = ocfs2_meta_lock(inode, NULL, 0); |
1190 | if (status < 0) { | 1183 | if (status < 0) { |
1191 | if (status != -ENOENT) | 1184 | if (status != -ENOENT) |
1192 | mlog_errno(status); | 1185 | mlog_errno(status); |
@@ -1204,7 +1197,7 @@ bail: | |||
1204 | * struct inode. | 1197 | * struct inode. |
1205 | * Only takes ip_lock. | 1198 | * Only takes ip_lock. |
1206 | */ | 1199 | */ |
1207 | int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle, | 1200 | int ocfs2_mark_inode_dirty(handle_t *handle, |
1208 | struct inode *inode, | 1201 | struct inode *inode, |
1209 | struct buffer_head *bh) | 1202 | struct buffer_head *bh) |
1210 | { | 1203 | { |
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index 9957810fdf85..1a7dd2945b34 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h | |||
@@ -48,13 +48,6 @@ struct ocfs2_inode_info | |||
48 | 48 | ||
49 | struct mutex ip_io_mutex; | 49 | struct mutex ip_io_mutex; |
50 | 50 | ||
51 | /* Used by the journalling code to attach an inode to a | ||
52 | * handle. These are protected by ip_io_mutex in order to lock | ||
53 | * out other I/O to the inode until we either commit or | ||
54 | * abort. */ | ||
55 | struct list_head ip_handle_list; | ||
56 | struct ocfs2_journal_handle *ip_handle; | ||
57 | |||
58 | u32 ip_flags; /* see below */ | 51 | u32 ip_flags; /* see below */ |
59 | u32 ip_attr; /* inode attributes */ | 52 | u32 ip_attr; /* inode attributes */ |
60 | 53 | ||
@@ -113,7 +106,7 @@ static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode) | |||
113 | #define INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags & OCFS2_INODE_JOURNAL) | 106 | #define INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags & OCFS2_INODE_JOURNAL) |
114 | #define SET_INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags |= OCFS2_INODE_JOURNAL) | 107 | #define SET_INODE_JOURNAL(i) (OCFS2_I(i)->ip_flags |= OCFS2_INODE_JOURNAL) |
115 | 108 | ||
116 | extern kmem_cache_t *ocfs2_inode_cache; | 109 | extern struct kmem_cache *ocfs2_inode_cache; |
117 | 110 | ||
118 | extern const struct address_space_operations ocfs2_aops; | 111 | extern const struct address_space_operations ocfs2_aops; |
119 | 112 | ||
@@ -143,7 +136,7 @@ ssize_t ocfs2_rw_direct(int rw, struct file *filp, char *buf, | |||
143 | void ocfs2_sync_blockdev(struct super_block *sb); | 136 | void ocfs2_sync_blockdev(struct super_block *sb); |
144 | void ocfs2_refresh_inode(struct inode *inode, | 137 | void ocfs2_refresh_inode(struct inode *inode, |
145 | struct ocfs2_dinode *fe); | 138 | struct ocfs2_dinode *fe); |
146 | int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle, | 139 | int ocfs2_mark_inode_dirty(handle_t *handle, |
147 | struct inode *inode, | 140 | struct inode *inode, |
148 | struct buffer_head *bh); | 141 | struct buffer_head *bh); |
149 | int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb); | 142 | int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb); |
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 3663cef80689..4768be5f3086 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
@@ -26,7 +26,7 @@ static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags) | |||
26 | { | 26 | { |
27 | int status; | 27 | int status; |
28 | 28 | ||
29 | status = ocfs2_meta_lock(inode, NULL, NULL, 0); | 29 | status = ocfs2_meta_lock(inode, NULL, 0); |
30 | if (status < 0) { | 30 | if (status < 0) { |
31 | mlog_errno(status); | 31 | mlog_errno(status); |
32 | return status; | 32 | return status; |
@@ -43,14 +43,14 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
43 | { | 43 | { |
44 | struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); | 44 | struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); |
45 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 45 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
46 | struct ocfs2_journal_handle *handle = NULL; | 46 | handle_t *handle = NULL; |
47 | struct buffer_head *bh = NULL; | 47 | struct buffer_head *bh = NULL; |
48 | unsigned oldflags; | 48 | unsigned oldflags; |
49 | int status; | 49 | int status; |
50 | 50 | ||
51 | mutex_lock(&inode->i_mutex); | 51 | mutex_lock(&inode->i_mutex); |
52 | 52 | ||
53 | status = ocfs2_meta_lock(inode, NULL, &bh, 1); | 53 | status = ocfs2_meta_lock(inode, &bh, 1); |
54 | if (status < 0) { | 54 | if (status < 0) { |
55 | mlog_errno(status); | 55 | mlog_errno(status); |
56 | goto bail; | 56 | goto bail; |
@@ -67,7 +67,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
67 | if (!S_ISDIR(inode->i_mode)) | 67 | if (!S_ISDIR(inode->i_mode)) |
68 | flags &= ~OCFS2_DIRSYNC_FL; | 68 | flags &= ~OCFS2_DIRSYNC_FL; |
69 | 69 | ||
70 | handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); | 70 | handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); |
71 | if (IS_ERR(handle)) { | 71 | if (IS_ERR(handle)) { |
72 | status = PTR_ERR(handle); | 72 | status = PTR_ERR(handle); |
73 | mlog_errno(status); | 73 | mlog_errno(status); |
@@ -96,7 +96,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, | |||
96 | if (status < 0) | 96 | if (status < 0) |
97 | mlog_errno(status); | 97 | mlog_errno(status); |
98 | 98 | ||
99 | ocfs2_commit_trans(handle); | 99 | ocfs2_commit_trans(osb, handle); |
100 | bail_unlock: | 100 | bail_unlock: |
101 | ocfs2_meta_unlock(inode, 1); | 101 | ocfs2_meta_unlock(inode, 1); |
102 | bail: | 102 | bail: |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index fd9734def551..1d7f4ab1e5ed 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
@@ -57,9 +57,6 @@ static int ocfs2_recover_node(struct ocfs2_super *osb, | |||
57 | static int __ocfs2_recovery_thread(void *arg); | 57 | static int __ocfs2_recovery_thread(void *arg); |
58 | static int ocfs2_commit_cache(struct ocfs2_super *osb); | 58 | static int ocfs2_commit_cache(struct ocfs2_super *osb); |
59 | static int ocfs2_wait_on_mount(struct ocfs2_super *osb); | 59 | static int ocfs2_wait_on_mount(struct ocfs2_super *osb); |
60 | static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal, | ||
61 | struct ocfs2_journal_handle *handle); | ||
62 | static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle); | ||
63 | static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, | 60 | static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, |
64 | int dirty); | 61 | int dirty); |
65 | static int ocfs2_trylock_journal(struct ocfs2_super *osb, | 62 | static int ocfs2_trylock_journal(struct ocfs2_super *osb, |
@@ -113,46 +110,18 @@ finally: | |||
113 | return status; | 110 | return status; |
114 | } | 111 | } |
115 | 112 | ||
116 | struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb) | ||
117 | { | ||
118 | struct ocfs2_journal_handle *retval = NULL; | ||
119 | |||
120 | retval = kcalloc(1, sizeof(*retval), GFP_NOFS); | ||
121 | if (!retval) { | ||
122 | mlog(ML_ERROR, "Failed to allocate memory for journal " | ||
123 | "handle!\n"); | ||
124 | return NULL; | ||
125 | } | ||
126 | |||
127 | retval->max_buffs = 0; | ||
128 | retval->num_locks = 0; | ||
129 | retval->k_handle = NULL; | ||
130 | |||
131 | INIT_LIST_HEAD(&retval->locks); | ||
132 | INIT_LIST_HEAD(&retval->inode_list); | ||
133 | retval->journal = osb->journal; | ||
134 | |||
135 | return retval; | ||
136 | } | ||
137 | |||
138 | /* pass it NULL and it will allocate a new handle object for you. If | 113 | /* pass it NULL and it will allocate a new handle object for you. If |
139 | * you pass it a handle however, it may still return error, in which | 114 | * you pass it a handle however, it may still return error, in which |
140 | * case it has free'd the passed handle for you. */ | 115 | * case it has free'd the passed handle for you. */ |
141 | struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, | 116 | handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs) |
142 | struct ocfs2_journal_handle *handle, | ||
143 | int max_buffs) | ||
144 | { | 117 | { |
145 | int ret; | ||
146 | journal_t *journal = osb->journal->j_journal; | 118 | journal_t *journal = osb->journal->j_journal; |
147 | 119 | handle_t *handle; | |
148 | mlog_entry("(max_buffs = %d)\n", max_buffs); | ||
149 | 120 | ||
150 | BUG_ON(!osb || !osb->journal->j_journal); | 121 | BUG_ON(!osb || !osb->journal->j_journal); |
151 | 122 | ||
152 | if (ocfs2_is_hard_readonly(osb)) { | 123 | if (ocfs2_is_hard_readonly(osb)) |
153 | ret = -EROFS; | 124 | return ERR_PTR(-EROFS); |
154 | goto done_free; | ||
155 | } | ||
156 | 125 | ||
157 | BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE); | 126 | BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE); |
158 | BUG_ON(max_buffs <= 0); | 127 | BUG_ON(max_buffs <= 0); |
@@ -163,154 +132,39 @@ struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, | |||
163 | BUG(); | 132 | BUG(); |
164 | } | 133 | } |
165 | 134 | ||
166 | if (!handle) | ||
167 | handle = ocfs2_alloc_handle(osb); | ||
168 | if (!handle) { | ||
169 | ret = -ENOMEM; | ||
170 | mlog(ML_ERROR, "Failed to allocate memory for journal " | ||
171 | "handle!\n"); | ||
172 | goto done_free; | ||
173 | } | ||
174 | |||
175 | handle->max_buffs = max_buffs; | ||
176 | |||
177 | down_read(&osb->journal->j_trans_barrier); | 135 | down_read(&osb->journal->j_trans_barrier); |
178 | 136 | ||
179 | /* actually start the transaction now */ | 137 | handle = journal_start(journal, max_buffs); |
180 | handle->k_handle = journal_start(journal, max_buffs); | 138 | if (IS_ERR(handle)) { |
181 | if (IS_ERR(handle->k_handle)) { | ||
182 | up_read(&osb->journal->j_trans_barrier); | 139 | up_read(&osb->journal->j_trans_barrier); |
183 | 140 | ||
184 | ret = PTR_ERR(handle->k_handle); | 141 | mlog_errno(PTR_ERR(handle)); |
185 | handle->k_handle = NULL; | ||
186 | mlog_errno(ret); | ||
187 | 142 | ||
188 | if (is_journal_aborted(journal)) { | 143 | if (is_journal_aborted(journal)) { |
189 | ocfs2_abort(osb->sb, "Detected aborted journal"); | 144 | ocfs2_abort(osb->sb, "Detected aborted journal"); |
190 | ret = -EROFS; | 145 | handle = ERR_PTR(-EROFS); |
191 | } | 146 | } |
192 | goto done_free; | 147 | } else |
193 | } | 148 | atomic_inc(&(osb->journal->j_num_trans)); |
194 | |||
195 | atomic_inc(&(osb->journal->j_num_trans)); | ||
196 | handle->flags |= OCFS2_HANDLE_STARTED; | ||
197 | 149 | ||
198 | mlog_exit_ptr(handle); | ||
199 | return handle; | 150 | return handle; |
200 | |||
201 | done_free: | ||
202 | if (handle) | ||
203 | ocfs2_commit_unstarted_handle(handle); /* will kfree handle */ | ||
204 | |||
205 | mlog_exit(ret); | ||
206 | return ERR_PTR(ret); | ||
207 | } | ||
208 | |||
209 | void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle, | ||
210 | struct inode *inode) | ||
211 | { | ||
212 | BUG_ON(!handle); | ||
213 | BUG_ON(!inode); | ||
214 | |||
215 | atomic_inc(&inode->i_count); | ||
216 | |||
217 | /* we're obviously changing it... */ | ||
218 | mutex_lock(&inode->i_mutex); | ||
219 | |||
220 | /* sanity check */ | ||
221 | BUG_ON(OCFS2_I(inode)->ip_handle); | ||
222 | BUG_ON(!list_empty(&OCFS2_I(inode)->ip_handle_list)); | ||
223 | |||
224 | OCFS2_I(inode)->ip_handle = handle; | ||
225 | list_move_tail(&(OCFS2_I(inode)->ip_handle_list), &(handle->inode_list)); | ||
226 | } | ||
227 | |||
228 | static void ocfs2_handle_unlock_inodes(struct ocfs2_journal_handle *handle) | ||
229 | { | ||
230 | struct list_head *p, *n; | ||
231 | struct inode *inode; | ||
232 | struct ocfs2_inode_info *oi; | ||
233 | |||
234 | list_for_each_safe(p, n, &handle->inode_list) { | ||
235 | oi = list_entry(p, struct ocfs2_inode_info, | ||
236 | ip_handle_list); | ||
237 | inode = &oi->vfs_inode; | ||
238 | |||
239 | OCFS2_I(inode)->ip_handle = NULL; | ||
240 | list_del_init(&OCFS2_I(inode)->ip_handle_list); | ||
241 | |||
242 | mutex_unlock(&inode->i_mutex); | ||
243 | iput(inode); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | /* This is trivial so we do it out of the main commit | ||
248 | * paths. Beware, it can be called from start_trans too! */ | ||
249 | static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle) | ||
250 | { | ||
251 | mlog_entry_void(); | ||
252 | |||
253 | BUG_ON(handle->flags & OCFS2_HANDLE_STARTED); | ||
254 | |||
255 | ocfs2_handle_unlock_inodes(handle); | ||
256 | /* You are allowed to add journal locks before the transaction | ||
257 | * has started. */ | ||
258 | ocfs2_handle_cleanup_locks(handle->journal, handle); | ||
259 | |||
260 | kfree(handle); | ||
261 | |||
262 | mlog_exit_void(); | ||
263 | } | 151 | } |
264 | 152 | ||
265 | void ocfs2_commit_trans(struct ocfs2_journal_handle *handle) | 153 | int ocfs2_commit_trans(struct ocfs2_super *osb, |
154 | handle_t *handle) | ||
266 | { | 155 | { |
267 | handle_t *jbd_handle; | 156 | int ret; |
268 | int retval; | 157 | struct ocfs2_journal *journal = osb->journal; |
269 | struct ocfs2_journal *journal = handle->journal; | ||
270 | |||
271 | mlog_entry_void(); | ||
272 | 158 | ||
273 | BUG_ON(!handle); | 159 | BUG_ON(!handle); |
274 | 160 | ||
275 | if (!(handle->flags & OCFS2_HANDLE_STARTED)) { | 161 | ret = journal_stop(handle); |
276 | ocfs2_commit_unstarted_handle(handle); | 162 | if (ret < 0) |
277 | mlog_exit_void(); | 163 | mlog_errno(ret); |
278 | return; | ||
279 | } | ||
280 | |||
281 | /* release inode semaphores we took during this transaction */ | ||
282 | ocfs2_handle_unlock_inodes(handle); | ||
283 | |||
284 | /* ocfs2_extend_trans may have had to call journal_restart | ||
285 | * which will always commit the transaction, but may return | ||
286 | * error for any number of reasons. If this is the case, we | ||
287 | * clear k_handle as it's not valid any more. */ | ||
288 | if (handle->k_handle) { | ||
289 | jbd_handle = handle->k_handle; | ||
290 | |||
291 | if (handle->flags & OCFS2_HANDLE_SYNC) | ||
292 | jbd_handle->h_sync = 1; | ||
293 | else | ||
294 | jbd_handle->h_sync = 0; | ||
295 | |||
296 | /* actually stop the transaction. if we've set h_sync, | ||
297 | * it'll have been committed when we return */ | ||
298 | retval = journal_stop(jbd_handle); | ||
299 | if (retval < 0) { | ||
300 | mlog_errno(retval); | ||
301 | mlog(ML_ERROR, "Could not commit transaction\n"); | ||
302 | BUG(); | ||
303 | } | ||
304 | |||
305 | handle->k_handle = NULL; /* it's been free'd in journal_stop */ | ||
306 | } | ||
307 | |||
308 | ocfs2_handle_cleanup_locks(journal, handle); | ||
309 | 164 | ||
310 | up_read(&journal->j_trans_barrier); | 165 | up_read(&journal->j_trans_barrier); |
311 | 166 | ||
312 | kfree(handle); | 167 | return ret; |
313 | mlog_exit_void(); | ||
314 | } | 168 | } |
315 | 169 | ||
316 | /* | 170 | /* |
@@ -326,20 +180,18 @@ void ocfs2_commit_trans(struct ocfs2_journal_handle *handle) | |||
326 | * good because transaction ids haven't yet been recorded on the | 180 | * good because transaction ids haven't yet been recorded on the |
327 | * cluster locks associated with this handle. | 181 | * cluster locks associated with this handle. |
328 | */ | 182 | */ |
329 | int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, | 183 | int ocfs2_extend_trans(handle_t *handle, int nblocks) |
330 | int nblocks) | ||
331 | { | 184 | { |
332 | int status; | 185 | int status; |
333 | 186 | ||
334 | BUG_ON(!handle); | 187 | BUG_ON(!handle); |
335 | BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED)); | ||
336 | BUG_ON(!nblocks); | 188 | BUG_ON(!nblocks); |
337 | 189 | ||
338 | mlog_entry_void(); | 190 | mlog_entry_void(); |
339 | 191 | ||
340 | mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); | 192 | mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); |
341 | 193 | ||
342 | status = journal_extend(handle->k_handle, nblocks); | 194 | status = journal_extend(handle, nblocks); |
343 | if (status < 0) { | 195 | if (status < 0) { |
344 | mlog_errno(status); | 196 | mlog_errno(status); |
345 | goto bail; | 197 | goto bail; |
@@ -347,15 +199,12 @@ int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, | |||
347 | 199 | ||
348 | if (status > 0) { | 200 | if (status > 0) { |
349 | mlog(0, "journal_extend failed, trying journal_restart\n"); | 201 | mlog(0, "journal_extend failed, trying journal_restart\n"); |
350 | status = journal_restart(handle->k_handle, nblocks); | 202 | status = journal_restart(handle, nblocks); |
351 | if (status < 0) { | 203 | if (status < 0) { |
352 | handle->k_handle = NULL; | ||
353 | mlog_errno(status); | 204 | mlog_errno(status); |
354 | goto bail; | 205 | goto bail; |
355 | } | 206 | } |
356 | handle->max_buffs = nblocks; | 207 | } |
357 | } else | ||
358 | handle->max_buffs += nblocks; | ||
359 | 208 | ||
360 | status = 0; | 209 | status = 0; |
361 | bail: | 210 | bail: |
@@ -364,7 +213,7 @@ bail: | |||
364 | return status; | 213 | return status; |
365 | } | 214 | } |
366 | 215 | ||
367 | int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | 216 | int ocfs2_journal_access(handle_t *handle, |
368 | struct inode *inode, | 217 | struct inode *inode, |
369 | struct buffer_head *bh, | 218 | struct buffer_head *bh, |
370 | int type) | 219 | int type) |
@@ -374,7 +223,6 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
374 | BUG_ON(!inode); | 223 | BUG_ON(!inode); |
375 | BUG_ON(!handle); | 224 | BUG_ON(!handle); |
376 | BUG_ON(!bh); | 225 | BUG_ON(!bh); |
377 | BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED)); | ||
378 | 226 | ||
379 | mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n", | 227 | mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n", |
380 | (unsigned long long)bh->b_blocknr, type, | 228 | (unsigned long long)bh->b_blocknr, type, |
@@ -403,11 +251,11 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
403 | switch (type) { | 251 | switch (type) { |
404 | case OCFS2_JOURNAL_ACCESS_CREATE: | 252 | case OCFS2_JOURNAL_ACCESS_CREATE: |
405 | case OCFS2_JOURNAL_ACCESS_WRITE: | 253 | case OCFS2_JOURNAL_ACCESS_WRITE: |
406 | status = journal_get_write_access(handle->k_handle, bh); | 254 | status = journal_get_write_access(handle, bh); |
407 | break; | 255 | break; |
408 | 256 | ||
409 | case OCFS2_JOURNAL_ACCESS_UNDO: | 257 | case OCFS2_JOURNAL_ACCESS_UNDO: |
410 | status = journal_get_undo_access(handle->k_handle, bh); | 258 | status = journal_get_undo_access(handle, bh); |
411 | break; | 259 | break; |
412 | 260 | ||
413 | default: | 261 | default: |
@@ -424,17 +272,15 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
424 | return status; | 272 | return status; |
425 | } | 273 | } |
426 | 274 | ||
427 | int ocfs2_journal_dirty(struct ocfs2_journal_handle *handle, | 275 | int ocfs2_journal_dirty(handle_t *handle, |
428 | struct buffer_head *bh) | 276 | struct buffer_head *bh) |
429 | { | 277 | { |
430 | int status; | 278 | int status; |
431 | 279 | ||
432 | BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED)); | ||
433 | |||
434 | mlog_entry("(bh->b_blocknr=%llu)\n", | 280 | mlog_entry("(bh->b_blocknr=%llu)\n", |
435 | (unsigned long long)bh->b_blocknr); | 281 | (unsigned long long)bh->b_blocknr); |
436 | 282 | ||
437 | status = journal_dirty_metadata(handle->k_handle, bh); | 283 | status = journal_dirty_metadata(handle, bh); |
438 | if (status < 0) | 284 | if (status < 0) |
439 | mlog(ML_ERROR, "Could not dirty metadata buffer. " | 285 | mlog(ML_ERROR, "Could not dirty metadata buffer. " |
440 | "(bh->b_blocknr=%llu)\n", | 286 | "(bh->b_blocknr=%llu)\n", |
@@ -456,59 +302,6 @@ int ocfs2_journal_dirty_data(handle_t *handle, | |||
456 | return err; | 302 | return err; |
457 | } | 303 | } |
458 | 304 | ||
459 | /* We always assume you're adding a metadata lock at level 'ex' */ | ||
460 | int ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle, | ||
461 | struct inode *inode) | ||
462 | { | ||
463 | int status; | ||
464 | struct ocfs2_journal_lock *lock; | ||
465 | |||
466 | BUG_ON(!inode); | ||
467 | |||
468 | lock = kmem_cache_alloc(ocfs2_lock_cache, GFP_NOFS); | ||
469 | if (!lock) { | ||
470 | status = -ENOMEM; | ||
471 | mlog_errno(-ENOMEM); | ||
472 | goto bail; | ||
473 | } | ||
474 | |||
475 | if (!igrab(inode)) | ||
476 | BUG(); | ||
477 | lock->jl_inode = inode; | ||
478 | |||
479 | list_add_tail(&(lock->jl_lock_list), &(handle->locks)); | ||
480 | handle->num_locks++; | ||
481 | |||
482 | status = 0; | ||
483 | bail: | ||
484 | mlog_exit(status); | ||
485 | return status; | ||
486 | } | ||
487 | |||
488 | static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal, | ||
489 | struct ocfs2_journal_handle *handle) | ||
490 | { | ||
491 | struct list_head *p, *n; | ||
492 | struct ocfs2_journal_lock *lock; | ||
493 | struct inode *inode; | ||
494 | |||
495 | list_for_each_safe(p, n, &(handle->locks)) { | ||
496 | lock = list_entry(p, struct ocfs2_journal_lock, | ||
497 | jl_lock_list); | ||
498 | list_del(&lock->jl_lock_list); | ||
499 | handle->num_locks--; | ||
500 | |||
501 | inode = lock->jl_inode; | ||
502 | ocfs2_meta_unlock(inode, 1); | ||
503 | if (atomic_read(&inode->i_count) == 1) | ||
504 | mlog(ML_ERROR, | ||
505 | "Inode %llu, I'm doing a last iput for!", | ||
506 | (unsigned long long)OCFS2_I(inode)->ip_blkno); | ||
507 | iput(inode); | ||
508 | kmem_cache_free(ocfs2_lock_cache, lock); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | #define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * 5) | 305 | #define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * 5) |
513 | 306 | ||
514 | void ocfs2_set_journal_params(struct ocfs2_super *osb) | 307 | void ocfs2_set_journal_params(struct ocfs2_super *osb) |
@@ -562,8 +355,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty) | |||
562 | /* Skip recovery waits here - journal inode metadata never | 355 | /* Skip recovery waits here - journal inode metadata never |
563 | * changes in a live cluster so it can be considered an | 356 | * changes in a live cluster so it can be considered an |
564 | * exception to the rule. */ | 357 | * exception to the rule. */ |
565 | status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, | 358 | status = ocfs2_meta_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY); |
566 | OCFS2_META_LOCK_RECOVERY); | ||
567 | if (status < 0) { | 359 | if (status < 0) { |
568 | if (status != -ERESTARTSYS) | 360 | if (status != -ERESTARTSYS) |
569 | mlog(ML_ERROR, "Could not get lock on journal!\n"); | 361 | mlog(ML_ERROR, "Could not get lock on journal!\n"); |
@@ -911,11 +703,12 @@ struct ocfs2_la_recovery_item { | |||
911 | * NOTE: This function can and will sleep on recovery of other nodes | 703 | * NOTE: This function can and will sleep on recovery of other nodes |
912 | * during cluster locking, just like any other ocfs2 process. | 704 | * during cluster locking, just like any other ocfs2 process. |
913 | */ | 705 | */ |
914 | void ocfs2_complete_recovery(void *data) | 706 | void ocfs2_complete_recovery(struct work_struct *work) |
915 | { | 707 | { |
916 | int ret; | 708 | int ret; |
917 | struct ocfs2_super *osb = data; | 709 | struct ocfs2_journal *journal = |
918 | struct ocfs2_journal *journal = osb->journal; | 710 | container_of(work, struct ocfs2_journal, j_recovery_work); |
711 | struct ocfs2_super *osb = journal->j_osb; | ||
919 | struct ocfs2_dinode *la_dinode, *tl_dinode; | 712 | struct ocfs2_dinode *la_dinode, *tl_dinode; |
920 | struct ocfs2_la_recovery_item *item; | 713 | struct ocfs2_la_recovery_item *item; |
921 | struct list_head *p, *n; | 714 | struct list_head *p, *n; |
@@ -1160,8 +953,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb, | |||
1160 | } | 953 | } |
1161 | SET_INODE_JOURNAL(inode); | 954 | SET_INODE_JOURNAL(inode); |
1162 | 955 | ||
1163 | status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, | 956 | status = ocfs2_meta_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY); |
1164 | OCFS2_META_LOCK_RECOVERY); | ||
1165 | if (status < 0) { | 957 | if (status < 0) { |
1166 | mlog(0, "status returned from ocfs2_meta_lock=%d\n", status); | 958 | mlog(0, "status returned from ocfs2_meta_lock=%d\n", status); |
1167 | if (status != -ERESTARTSYS) | 959 | if (status != -ERESTARTSYS) |
@@ -1350,7 +1142,7 @@ static int ocfs2_trylock_journal(struct ocfs2_super *osb, | |||
1350 | SET_INODE_JOURNAL(inode); | 1142 | SET_INODE_JOURNAL(inode); |
1351 | 1143 | ||
1352 | flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE; | 1144 | flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE; |
1353 | status = ocfs2_meta_lock_full(inode, NULL, NULL, 1, flags); | 1145 | status = ocfs2_meta_lock_full(inode, NULL, 1, flags); |
1354 | if (status < 0) { | 1146 | if (status < 0) { |
1355 | if (status != -EAGAIN) | 1147 | if (status != -EAGAIN) |
1356 | mlog_errno(status); | 1148 | mlog_errno(status); |
@@ -1433,7 +1225,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb, | |||
1433 | } | 1225 | } |
1434 | 1226 | ||
1435 | mutex_lock(&orphan_dir_inode->i_mutex); | 1227 | mutex_lock(&orphan_dir_inode->i_mutex); |
1436 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0); | 1228 | status = ocfs2_meta_lock(orphan_dir_inode, NULL, 0); |
1437 | if (status < 0) { | 1229 | if (status < 0) { |
1438 | mlog_errno(status); | 1230 | mlog_errno(status); |
1439 | goto out; | 1231 | goto out; |
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h index 2f3a6acdac45..899112ad8136 100644 --- a/fs/ocfs2/journal.h +++ b/fs/ocfs2/journal.h | |||
@@ -37,7 +37,6 @@ enum ocfs2_journal_state { | |||
37 | 37 | ||
38 | struct ocfs2_super; | 38 | struct ocfs2_super; |
39 | struct ocfs2_dinode; | 39 | struct ocfs2_dinode; |
40 | struct ocfs2_journal_handle; | ||
41 | 40 | ||
42 | struct ocfs2_journal { | 41 | struct ocfs2_journal { |
43 | enum ocfs2_journal_state j_state; /* Journals current state */ | 42 | enum ocfs2_journal_state j_state; /* Journals current state */ |
@@ -133,46 +132,8 @@ static inline void ocfs2_inode_set_new(struct ocfs2_super *osb, | |||
133 | spin_unlock(&trans_inc_lock); | 132 | spin_unlock(&trans_inc_lock); |
134 | } | 133 | } |
135 | 134 | ||
136 | extern kmem_cache_t *ocfs2_lock_cache; | ||
137 | |||
138 | struct ocfs2_journal_lock { | ||
139 | struct inode *jl_inode; | ||
140 | struct list_head jl_lock_list; | ||
141 | }; | ||
142 | |||
143 | struct ocfs2_journal_handle { | ||
144 | handle_t *k_handle; /* kernel handle. */ | ||
145 | struct ocfs2_journal *journal; | ||
146 | u32 flags; /* see flags below. */ | ||
147 | int max_buffs; /* Buffs reserved by this handle */ | ||
148 | |||
149 | /* The following two fields are for ocfs2_handle_add_lock */ | ||
150 | int num_locks; | ||
151 | struct list_head locks; /* A bunch of locks to | ||
152 | * release on commit. This | ||
153 | * should be a list_head */ | ||
154 | |||
155 | struct list_head inode_list; | ||
156 | }; | ||
157 | |||
158 | #define OCFS2_HANDLE_STARTED 1 | ||
159 | /* should we sync-commit this handle? */ | ||
160 | #define OCFS2_HANDLE_SYNC 2 | ||
161 | static inline int ocfs2_handle_started(struct ocfs2_journal_handle *handle) | ||
162 | { | ||
163 | return handle->flags & OCFS2_HANDLE_STARTED; | ||
164 | } | ||
165 | |||
166 | static inline void ocfs2_handle_set_sync(struct ocfs2_journal_handle *handle, int sync) | ||
167 | { | ||
168 | if (sync) | ||
169 | handle->flags |= OCFS2_HANDLE_SYNC; | ||
170 | else | ||
171 | handle->flags &= ~OCFS2_HANDLE_SYNC; | ||
172 | } | ||
173 | |||
174 | /* Exported only for the journal struct init code in super.c. Do not call. */ | 135 | /* Exported only for the journal struct init code in super.c. Do not call. */ |
175 | void ocfs2_complete_recovery(void *data); | 136 | void ocfs2_complete_recovery(struct work_struct *work); |
176 | 137 | ||
177 | /* | 138 | /* |
178 | * Journal Control: | 139 | * Journal Control: |
@@ -231,15 +192,14 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
231 | * Transaction Handling: | 192 | * Transaction Handling: |
232 | * Manage the lifetime of a transaction handle. | 193 | * Manage the lifetime of a transaction handle. |
233 | * | 194 | * |
234 | * ocfs2_alloc_handle - Only allocate a handle so we can start putting | ||
235 | * cluster locks on it. To actually change blocks, | ||
236 | * call ocfs2_start_trans with the handle returned | ||
237 | * from this function. You may call ocfs2_commit_trans | ||
238 | * at any time in the lifetime of a handle. | ||
239 | * ocfs2_start_trans - Begin a transaction. Give it an upper estimate of | 195 | * ocfs2_start_trans - Begin a transaction. Give it an upper estimate of |
240 | * the number of blocks that will be changed during | 196 | * the number of blocks that will be changed during |
241 | * this handle. | 197 | * this handle. |
242 | * ocfs2_commit_trans - Complete a handle. | 198 | * ocfs2_commit_trans - Complete a handle. It might return -EIO if |
199 | * the journal was aborted. The majority of paths don't | ||
200 | * check the return value as an error there comes too | ||
201 | * late to do anything (and will be picked up in a | ||
202 | * later transaction). | ||
243 | * ocfs2_extend_trans - Extend a handle by nblocks credits. This may | 203 | * ocfs2_extend_trans - Extend a handle by nblocks credits. This may |
244 | * commit the handle to disk in the process, but will | 204 | * commit the handle to disk in the process, but will |
245 | * not release any locks taken during the transaction. | 205 | * not release any locks taken during the transaction. |
@@ -249,24 +209,16 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode) | |||
249 | * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data. | 209 | * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data. |
250 | * ocfs2_journal_dirty_data - Indicate that a data buffer should go out before | 210 | * ocfs2_journal_dirty_data - Indicate that a data buffer should go out before |
251 | * the current handle commits. | 211 | * the current handle commits. |
252 | * ocfs2_handle_add_lock - Sometimes we need to delay lock release | ||
253 | * until after a transaction has been completed. Use | ||
254 | * ocfs2_handle_add_lock to indicate that a lock needs | ||
255 | * to be released at the end of that handle. Locks | ||
256 | * will be released in the order that they are added. | ||
257 | * ocfs2_handle_add_inode - Add a locked inode to a transaction. | ||
258 | */ | 212 | */ |
259 | 213 | ||
260 | /* You must always start_trans with a number of buffs > 0, but it's | 214 | /* You must always start_trans with a number of buffs > 0, but it's |
261 | * perfectly legal to go through an entire transaction without having | 215 | * perfectly legal to go through an entire transaction without having |
262 | * dirtied any buffers. */ | 216 | * dirtied any buffers. */ |
263 | struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb); | 217 | handle_t *ocfs2_start_trans(struct ocfs2_super *osb, |
264 | struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, | ||
265 | struct ocfs2_journal_handle *handle, | ||
266 | int max_buffs); | 218 | int max_buffs); |
267 | void ocfs2_commit_trans(struct ocfs2_journal_handle *handle); | 219 | int ocfs2_commit_trans(struct ocfs2_super *osb, |
268 | int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, | 220 | handle_t *handle); |
269 | int nblocks); | 221 | int ocfs2_extend_trans(handle_t *handle, int nblocks); |
270 | 222 | ||
271 | /* | 223 | /* |
272 | * Create access is for when we get a newly created buffer and we're | 224 | * Create access is for when we get a newly created buffer and we're |
@@ -283,7 +235,7 @@ int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, | |||
283 | #define OCFS2_JOURNAL_ACCESS_WRITE 1 | 235 | #define OCFS2_JOURNAL_ACCESS_WRITE 1 |
284 | #define OCFS2_JOURNAL_ACCESS_UNDO 2 | 236 | #define OCFS2_JOURNAL_ACCESS_UNDO 2 |
285 | 237 | ||
286 | int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | 238 | int ocfs2_journal_access(handle_t *handle, |
287 | struct inode *inode, | 239 | struct inode *inode, |
288 | struct buffer_head *bh, | 240 | struct buffer_head *bh, |
289 | int type); | 241 | int type); |
@@ -306,18 +258,10 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
306 | * <modify the bh> | 258 | * <modify the bh> |
307 | * ocfs2_journal_dirty(handle, bh); | 259 | * ocfs2_journal_dirty(handle, bh); |
308 | */ | 260 | */ |
309 | int ocfs2_journal_dirty(struct ocfs2_journal_handle *handle, | 261 | int ocfs2_journal_dirty(handle_t *handle, |
310 | struct buffer_head *bh); | 262 | struct buffer_head *bh); |
311 | int ocfs2_journal_dirty_data(handle_t *handle, | 263 | int ocfs2_journal_dirty_data(handle_t *handle, |
312 | struct buffer_head *bh); | 264 | struct buffer_head *bh); |
313 | int ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle, | ||
314 | struct inode *inode); | ||
315 | /* | ||
316 | * Use this to protect from other processes reading buffer state while | ||
317 | * it's in flight. | ||
318 | */ | ||
319 | void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle, | ||
320 | struct inode *inode); | ||
321 | 265 | ||
322 | /* | 266 | /* |
323 | * Credit Macros: | 267 | * Credit Macros: |
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 1f17a4d08287..698d79a74ef8 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
@@ -58,19 +58,18 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb, | |||
58 | static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc); | 58 | static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc); |
59 | 59 | ||
60 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, | 60 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, |
61 | struct ocfs2_journal_handle *handle, | 61 | handle_t *handle, |
62 | struct ocfs2_dinode *alloc, | 62 | struct ocfs2_dinode *alloc, |
63 | struct inode *main_bm_inode, | 63 | struct inode *main_bm_inode, |
64 | struct buffer_head *main_bm_bh); | 64 | struct buffer_head *main_bm_bh); |
65 | 65 | ||
66 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, | 66 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, |
67 | struct ocfs2_journal_handle *handle, | ||
68 | struct ocfs2_alloc_context **ac, | 67 | struct ocfs2_alloc_context **ac, |
69 | struct inode **bitmap_inode, | 68 | struct inode **bitmap_inode, |
70 | struct buffer_head **bitmap_bh); | 69 | struct buffer_head **bitmap_bh); |
71 | 70 | ||
72 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, | 71 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, |
73 | struct ocfs2_journal_handle *handle, | 72 | handle_t *handle, |
74 | struct ocfs2_alloc_context *ac); | 73 | struct ocfs2_alloc_context *ac); |
75 | 74 | ||
76 | static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | 75 | static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, |
@@ -196,7 +195,7 @@ bail: | |||
196 | void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | 195 | void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) |
197 | { | 196 | { |
198 | int status; | 197 | int status; |
199 | struct ocfs2_journal_handle *handle = NULL; | 198 | handle_t *handle; |
200 | struct inode *local_alloc_inode = NULL; | 199 | struct inode *local_alloc_inode = NULL; |
201 | struct buffer_head *bh = NULL; | 200 | struct buffer_head *bh = NULL; |
202 | struct buffer_head *main_bm_bh = NULL; | 201 | struct buffer_head *main_bm_bh = NULL; |
@@ -207,7 +206,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
207 | mlog_entry_void(); | 206 | mlog_entry_void(); |
208 | 207 | ||
209 | if (osb->local_alloc_state == OCFS2_LA_UNUSED) | 208 | if (osb->local_alloc_state == OCFS2_LA_UNUSED) |
210 | goto bail; | 209 | goto out; |
211 | 210 | ||
212 | local_alloc_inode = | 211 | local_alloc_inode = |
213 | ocfs2_get_system_file_inode(osb, | 212 | ocfs2_get_system_file_inode(osb, |
@@ -216,40 +215,34 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
216 | if (!local_alloc_inode) { | 215 | if (!local_alloc_inode) { |
217 | status = -ENOENT; | 216 | status = -ENOENT; |
218 | mlog_errno(status); | 217 | mlog_errno(status); |
219 | goto bail; | 218 | goto out; |
220 | } | 219 | } |
221 | 220 | ||
222 | osb->local_alloc_state = OCFS2_LA_DISABLED; | 221 | osb->local_alloc_state = OCFS2_LA_DISABLED; |
223 | 222 | ||
224 | handle = ocfs2_alloc_handle(osb); | ||
225 | if (!handle) { | ||
226 | status = -ENOMEM; | ||
227 | mlog_errno(status); | ||
228 | goto bail; | ||
229 | } | ||
230 | |||
231 | main_bm_inode = ocfs2_get_system_file_inode(osb, | 223 | main_bm_inode = ocfs2_get_system_file_inode(osb, |
232 | GLOBAL_BITMAP_SYSTEM_INODE, | 224 | GLOBAL_BITMAP_SYSTEM_INODE, |
233 | OCFS2_INVALID_SLOT); | 225 | OCFS2_INVALID_SLOT); |
234 | if (!main_bm_inode) { | 226 | if (!main_bm_inode) { |
235 | status = -EINVAL; | 227 | status = -EINVAL; |
236 | mlog_errno(status); | 228 | mlog_errno(status); |
237 | goto bail; | 229 | goto out; |
238 | } | 230 | } |
239 | 231 | ||
240 | ocfs2_handle_add_inode(handle, main_bm_inode); | 232 | mutex_lock(&main_bm_inode->i_mutex); |
241 | status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1); | 233 | |
234 | status = ocfs2_meta_lock(main_bm_inode, &main_bm_bh, 1); | ||
242 | if (status < 0) { | 235 | if (status < 0) { |
243 | mlog_errno(status); | 236 | mlog_errno(status); |
244 | goto bail; | 237 | goto out_mutex; |
245 | } | 238 | } |
246 | 239 | ||
247 | /* WINDOW_MOVE_CREDITS is a bit heavy... */ | 240 | /* WINDOW_MOVE_CREDITS is a bit heavy... */ |
248 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 241 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
249 | if (IS_ERR(handle)) { | 242 | if (IS_ERR(handle)) { |
250 | mlog_errno(PTR_ERR(handle)); | 243 | mlog_errno(PTR_ERR(handle)); |
251 | handle = NULL; | 244 | handle = NULL; |
252 | goto bail; | 245 | goto out_unlock; |
253 | } | 246 | } |
254 | 247 | ||
255 | bh = osb->local_alloc_bh; | 248 | bh = osb->local_alloc_bh; |
@@ -258,7 +251,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
258 | alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); | 251 | alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); |
259 | if (!alloc_copy) { | 252 | if (!alloc_copy) { |
260 | status = -ENOMEM; | 253 | status = -ENOMEM; |
261 | goto bail; | 254 | goto out_commit; |
262 | } | 255 | } |
263 | memcpy(alloc_copy, alloc, bh->b_size); | 256 | memcpy(alloc_copy, alloc, bh->b_size); |
264 | 257 | ||
@@ -266,7 +259,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
266 | OCFS2_JOURNAL_ACCESS_WRITE); | 259 | OCFS2_JOURNAL_ACCESS_WRITE); |
267 | if (status < 0) { | 260 | if (status < 0) { |
268 | mlog_errno(status); | 261 | mlog_errno(status); |
269 | goto bail; | 262 | goto out_commit; |
270 | } | 263 | } |
271 | 264 | ||
272 | ocfs2_clear_local_alloc(alloc); | 265 | ocfs2_clear_local_alloc(alloc); |
@@ -274,7 +267,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
274 | status = ocfs2_journal_dirty(handle, bh); | 267 | status = ocfs2_journal_dirty(handle, bh); |
275 | if (status < 0) { | 268 | if (status < 0) { |
276 | mlog_errno(status); | 269 | mlog_errno(status); |
277 | goto bail; | 270 | goto out_commit; |
278 | } | 271 | } |
279 | 272 | ||
280 | brelse(bh); | 273 | brelse(bh); |
@@ -286,16 +279,20 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) | |||
286 | if (status < 0) | 279 | if (status < 0) |
287 | mlog_errno(status); | 280 | mlog_errno(status); |
288 | 281 | ||
289 | bail: | 282 | out_commit: |
290 | if (handle) | 283 | ocfs2_commit_trans(osb, handle); |
291 | ocfs2_commit_trans(handle); | ||
292 | 284 | ||
285 | out_unlock: | ||
293 | if (main_bm_bh) | 286 | if (main_bm_bh) |
294 | brelse(main_bm_bh); | 287 | brelse(main_bm_bh); |
295 | 288 | ||
296 | if (main_bm_inode) | 289 | ocfs2_meta_unlock(main_bm_inode, 1); |
297 | iput(main_bm_inode); | ||
298 | 290 | ||
291 | out_mutex: | ||
292 | mutex_unlock(&main_bm_inode->i_mutex); | ||
293 | iput(main_bm_inode); | ||
294 | |||
295 | out: | ||
299 | if (local_alloc_inode) | 296 | if (local_alloc_inode) |
300 | iput(local_alloc_inode); | 297 | iput(local_alloc_inode); |
301 | 298 | ||
@@ -385,61 +382,59 @@ int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb, | |||
385 | struct ocfs2_dinode *alloc) | 382 | struct ocfs2_dinode *alloc) |
386 | { | 383 | { |
387 | int status; | 384 | int status; |
388 | struct ocfs2_journal_handle *handle = NULL; | 385 | handle_t *handle; |
389 | struct buffer_head *main_bm_bh = NULL; | 386 | struct buffer_head *main_bm_bh = NULL; |
390 | struct inode *main_bm_inode = NULL; | 387 | struct inode *main_bm_inode; |
391 | 388 | ||
392 | mlog_entry_void(); | 389 | mlog_entry_void(); |
393 | 390 | ||
394 | handle = ocfs2_alloc_handle(osb); | ||
395 | if (!handle) { | ||
396 | status = -ENOMEM; | ||
397 | mlog_errno(status); | ||
398 | goto bail; | ||
399 | } | ||
400 | |||
401 | main_bm_inode = ocfs2_get_system_file_inode(osb, | 391 | main_bm_inode = ocfs2_get_system_file_inode(osb, |
402 | GLOBAL_BITMAP_SYSTEM_INODE, | 392 | GLOBAL_BITMAP_SYSTEM_INODE, |
403 | OCFS2_INVALID_SLOT); | 393 | OCFS2_INVALID_SLOT); |
404 | if (!main_bm_inode) { | 394 | if (!main_bm_inode) { |
405 | status = -EINVAL; | 395 | status = -EINVAL; |
406 | mlog_errno(status); | 396 | mlog_errno(status); |
407 | goto bail; | 397 | goto out; |
408 | } | 398 | } |
409 | 399 | ||
410 | ocfs2_handle_add_inode(handle, main_bm_inode); | 400 | mutex_lock(&main_bm_inode->i_mutex); |
411 | status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1); | 401 | |
402 | status = ocfs2_meta_lock(main_bm_inode, &main_bm_bh, 1); | ||
412 | if (status < 0) { | 403 | if (status < 0) { |
413 | mlog_errno(status); | 404 | mlog_errno(status); |
414 | goto bail; | 405 | goto out_mutex; |
415 | } | 406 | } |
416 | 407 | ||
417 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 408 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
418 | if (IS_ERR(handle)) { | 409 | if (IS_ERR(handle)) { |
419 | status = PTR_ERR(handle); | 410 | status = PTR_ERR(handle); |
420 | handle = NULL; | 411 | handle = NULL; |
421 | mlog_errno(status); | 412 | mlog_errno(status); |
422 | goto bail; | 413 | goto out_unlock; |
423 | } | 414 | } |
424 | 415 | ||
425 | /* we want the bitmap change to be recorded on disk asap */ | 416 | /* we want the bitmap change to be recorded on disk asap */ |
426 | ocfs2_handle_set_sync(handle, 1); | 417 | handle->h_sync = 1; |
427 | 418 | ||
428 | status = ocfs2_sync_local_to_main(osb, handle, alloc, | 419 | status = ocfs2_sync_local_to_main(osb, handle, alloc, |
429 | main_bm_inode, main_bm_bh); | 420 | main_bm_inode, main_bm_bh); |
430 | if (status < 0) | 421 | if (status < 0) |
431 | mlog_errno(status); | 422 | mlog_errno(status); |
432 | 423 | ||
433 | bail: | 424 | ocfs2_commit_trans(osb, handle); |
434 | if (handle) | 425 | |
435 | ocfs2_commit_trans(handle); | 426 | out_unlock: |
427 | ocfs2_meta_unlock(main_bm_inode, 1); | ||
428 | |||
429 | out_mutex: | ||
430 | mutex_unlock(&main_bm_inode->i_mutex); | ||
436 | 431 | ||
437 | if (main_bm_bh) | 432 | if (main_bm_bh) |
438 | brelse(main_bm_bh); | 433 | brelse(main_bm_bh); |
439 | 434 | ||
440 | if (main_bm_inode) | 435 | iput(main_bm_inode); |
441 | iput(main_bm_inode); | ||
442 | 436 | ||
437 | out: | ||
443 | mlog_exit(status); | 438 | mlog_exit(status); |
444 | return status; | 439 | return status; |
445 | } | 440 | } |
@@ -452,7 +447,6 @@ bail: | |||
452 | * our own in order to shift windows. | 447 | * our own in order to shift windows. |
453 | */ | 448 | */ |
454 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | 449 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, |
455 | struct ocfs2_journal_handle *passed_handle, | ||
456 | u32 bits_wanted, | 450 | u32 bits_wanted, |
457 | struct ocfs2_alloc_context *ac) | 451 | struct ocfs2_alloc_context *ac) |
458 | { | 452 | { |
@@ -463,9 +457,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
463 | 457 | ||
464 | mlog_entry_void(); | 458 | mlog_entry_void(); |
465 | 459 | ||
466 | BUG_ON(!passed_handle); | ||
467 | BUG_ON(!ac); | 460 | BUG_ON(!ac); |
468 | BUG_ON(passed_handle->flags & OCFS2_HANDLE_STARTED); | ||
469 | 461 | ||
470 | local_alloc_inode = | 462 | local_alloc_inode = |
471 | ocfs2_get_system_file_inode(osb, | 463 | ocfs2_get_system_file_inode(osb, |
@@ -476,7 +468,11 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
476 | mlog_errno(status); | 468 | mlog_errno(status); |
477 | goto bail; | 469 | goto bail; |
478 | } | 470 | } |
479 | ocfs2_handle_add_inode(passed_handle, local_alloc_inode); | 471 | |
472 | mutex_lock(&local_alloc_inode->i_mutex); | ||
473 | |||
474 | ac->ac_inode = local_alloc_inode; | ||
475 | ac->ac_which = OCFS2_AC_USE_LOCAL; | ||
480 | 476 | ||
481 | if (osb->local_alloc_state != OCFS2_LA_ENABLED) { | 477 | if (osb->local_alloc_state != OCFS2_LA_ENABLED) { |
482 | status = -ENOSPC; | 478 | status = -ENOSPC; |
@@ -515,21 +511,17 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | |||
515 | } | 511 | } |
516 | } | 512 | } |
517 | 513 | ||
518 | ac->ac_inode = igrab(local_alloc_inode); | ||
519 | get_bh(osb->local_alloc_bh); | 514 | get_bh(osb->local_alloc_bh); |
520 | ac->ac_bh = osb->local_alloc_bh; | 515 | ac->ac_bh = osb->local_alloc_bh; |
521 | ac->ac_which = OCFS2_AC_USE_LOCAL; | ||
522 | status = 0; | 516 | status = 0; |
523 | bail: | 517 | bail: |
524 | if (local_alloc_inode) | ||
525 | iput(local_alloc_inode); | ||
526 | 518 | ||
527 | mlog_exit(status); | 519 | mlog_exit(status); |
528 | return status; | 520 | return status; |
529 | } | 521 | } |
530 | 522 | ||
531 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | 523 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, |
532 | struct ocfs2_journal_handle *handle, | 524 | handle_t *handle, |
533 | struct ocfs2_alloc_context *ac, | 525 | struct ocfs2_alloc_context *ac, |
534 | u32 min_bits, | 526 | u32 min_bits, |
535 | u32 *bit_off, | 527 | u32 *bit_off, |
@@ -707,7 +699,7 @@ static void ocfs2_verify_zero_bits(unsigned long *bitmap, | |||
707 | * passed is used for caching. | 699 | * passed is used for caching. |
708 | */ | 700 | */ |
709 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, | 701 | static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, |
710 | struct ocfs2_journal_handle *handle, | 702 | handle_t *handle, |
711 | struct ocfs2_dinode *alloc, | 703 | struct ocfs2_dinode *alloc, |
712 | struct inode *main_bm_inode, | 704 | struct inode *main_bm_inode, |
713 | struct buffer_head *main_bm_bh) | 705 | struct buffer_head *main_bm_bh) |
@@ -778,7 +770,6 @@ bail: | |||
778 | } | 770 | } |
779 | 771 | ||
780 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, | 772 | static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, |
781 | struct ocfs2_journal_handle *handle, | ||
782 | struct ocfs2_alloc_context **ac, | 773 | struct ocfs2_alloc_context **ac, |
783 | struct inode **bitmap_inode, | 774 | struct inode **bitmap_inode, |
784 | struct buffer_head **bitmap_bh) | 775 | struct buffer_head **bitmap_bh) |
@@ -792,7 +783,6 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, | |||
792 | goto bail; | 783 | goto bail; |
793 | } | 784 | } |
794 | 785 | ||
795 | (*ac)->ac_handle = handle; | ||
796 | (*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb); | 786 | (*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb); |
797 | 787 | ||
798 | status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac); | 788 | status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac); |
@@ -821,7 +811,7 @@ bail: | |||
821 | * pass it the bitmap lock in lock_bh if you have it. | 811 | * pass it the bitmap lock in lock_bh if you have it. |
822 | */ | 812 | */ |
823 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, | 813 | static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, |
824 | struct ocfs2_journal_handle *handle, | 814 | handle_t *handle, |
825 | struct ocfs2_alloc_context *ac) | 815 | struct ocfs2_alloc_context *ac) |
826 | { | 816 | { |
827 | int status = 0; | 817 | int status = 0; |
@@ -888,23 +878,15 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
888 | int status = 0; | 878 | int status = 0; |
889 | struct buffer_head *main_bm_bh = NULL; | 879 | struct buffer_head *main_bm_bh = NULL; |
890 | struct inode *main_bm_inode = NULL; | 880 | struct inode *main_bm_inode = NULL; |
891 | struct ocfs2_journal_handle *handle = NULL; | 881 | handle_t *handle = NULL; |
892 | struct ocfs2_dinode *alloc; | 882 | struct ocfs2_dinode *alloc; |
893 | struct ocfs2_dinode *alloc_copy = NULL; | 883 | struct ocfs2_dinode *alloc_copy = NULL; |
894 | struct ocfs2_alloc_context *ac = NULL; | 884 | struct ocfs2_alloc_context *ac = NULL; |
895 | 885 | ||
896 | mlog_entry_void(); | 886 | mlog_entry_void(); |
897 | 887 | ||
898 | handle = ocfs2_alloc_handle(osb); | ||
899 | if (!handle) { | ||
900 | status = -ENOMEM; | ||
901 | mlog_errno(status); | ||
902 | goto bail; | ||
903 | } | ||
904 | |||
905 | /* This will lock the main bitmap for us. */ | 888 | /* This will lock the main bitmap for us. */ |
906 | status = ocfs2_local_alloc_reserve_for_window(osb, | 889 | status = ocfs2_local_alloc_reserve_for_window(osb, |
907 | handle, | ||
908 | &ac, | 890 | &ac, |
909 | &main_bm_inode, | 891 | &main_bm_inode, |
910 | &main_bm_bh); | 892 | &main_bm_bh); |
@@ -914,7 +896,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
914 | goto bail; | 896 | goto bail; |
915 | } | 897 | } |
916 | 898 | ||
917 | handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); | 899 | handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS); |
918 | if (IS_ERR(handle)) { | 900 | if (IS_ERR(handle)) { |
919 | status = PTR_ERR(handle); | 901 | status = PTR_ERR(handle); |
920 | handle = NULL; | 902 | handle = NULL; |
@@ -972,7 +954,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, | |||
972 | status = 0; | 954 | status = 0; |
973 | bail: | 955 | bail: |
974 | if (handle) | 956 | if (handle) |
975 | ocfs2_commit_trans(handle); | 957 | ocfs2_commit_trans(osb, handle); |
976 | 958 | ||
977 | if (main_bm_bh) | 959 | if (main_bm_bh) |
978 | brelse(main_bm_bh); | 960 | brelse(main_bm_bh); |
diff --git a/fs/ocfs2/localalloc.h b/fs/ocfs2/localalloc.h index 30f88ce14e46..385a10152f9c 100644 --- a/fs/ocfs2/localalloc.h +++ b/fs/ocfs2/localalloc.h | |||
@@ -42,12 +42,11 @@ int ocfs2_alloc_should_use_local(struct ocfs2_super *osb, | |||
42 | 42 | ||
43 | struct ocfs2_alloc_context; | 43 | struct ocfs2_alloc_context; |
44 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, | 44 | int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, |
45 | struct ocfs2_journal_handle *passed_handle, | ||
46 | u32 bits_wanted, | 45 | u32 bits_wanted, |
47 | struct ocfs2_alloc_context *ac); | 46 | struct ocfs2_alloc_context *ac); |
48 | 47 | ||
49 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | 48 | int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, |
50 | struct ocfs2_journal_handle *handle, | 49 | handle_t *handle, |
51 | struct ocfs2_alloc_context *ac, | 50 | struct ocfs2_alloc_context *ac, |
52 | u32 min_bits, | 51 | u32 min_bits, |
53 | u32 *bit_off, | 52 | u32 *bit_off, |
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c index 83934e33e5b0..69f85ae392dc 100644 --- a/fs/ocfs2/mmap.c +++ b/fs/ocfs2/mmap.c | |||
@@ -82,6 +82,8 @@ static struct vm_operations_struct ocfs2_file_vm_ops = { | |||
82 | 82 | ||
83 | int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) | 83 | int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) |
84 | { | 84 | { |
85 | int ret = 0, lock_level = 0; | ||
86 | |||
85 | /* We don't want to support shared writable mappings yet. */ | 87 | /* We don't want to support shared writable mappings yet. */ |
86 | if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) | 88 | if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) |
87 | && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) { | 89 | && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) { |
@@ -91,7 +93,14 @@ int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) | |||
91 | return -EINVAL; | 93 | return -EINVAL; |
92 | } | 94 | } |
93 | 95 | ||
94 | file_accessed(file); | 96 | ret = ocfs2_meta_lock_atime(file->f_dentry->d_inode, |
97 | file->f_vfsmnt, &lock_level); | ||
98 | if (ret < 0) { | ||
99 | mlog_errno(ret); | ||
100 | goto out; | ||
101 | } | ||
102 | ocfs2_meta_unlock(file->f_dentry->d_inode, lock_level); | ||
103 | out: | ||
95 | vma->vm_ops = &ocfs2_file_vm_ops; | 104 | vma->vm_ops = &ocfs2_file_vm_ops; |
96 | return 0; | 105 | return 0; |
97 | } | 106 | } |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index a57b751d4f40..21db45ddf144 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -75,12 +75,12 @@ static int inline ocfs2_search_dirblock(struct buffer_head *bh, | |||
75 | unsigned long offset, | 75 | unsigned long offset, |
76 | struct ocfs2_dir_entry **res_dir); | 76 | struct ocfs2_dir_entry **res_dir); |
77 | 77 | ||
78 | static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, | 78 | static int ocfs2_delete_entry(handle_t *handle, |
79 | struct inode *dir, | 79 | struct inode *dir, |
80 | struct ocfs2_dir_entry *de_del, | 80 | struct ocfs2_dir_entry *de_del, |
81 | struct buffer_head *bh); | 81 | struct buffer_head *bh); |
82 | 82 | ||
83 | static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 83 | static int __ocfs2_add_entry(handle_t *handle, |
84 | struct inode *dir, | 84 | struct inode *dir, |
85 | const char *name, int namelen, | 85 | const char *name, int namelen, |
86 | struct inode *inode, u64 blkno, | 86 | struct inode *inode, u64 blkno, |
@@ -93,43 +93,37 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
93 | dev_t dev, | 93 | dev_t dev, |
94 | struct buffer_head **new_fe_bh, | 94 | struct buffer_head **new_fe_bh, |
95 | struct buffer_head *parent_fe_bh, | 95 | struct buffer_head *parent_fe_bh, |
96 | struct ocfs2_journal_handle *handle, | 96 | handle_t *handle, |
97 | struct inode **ret_inode, | 97 | struct inode **ret_inode, |
98 | struct ocfs2_alloc_context *inode_ac); | 98 | struct ocfs2_alloc_context *inode_ac); |
99 | 99 | ||
100 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, | 100 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, |
101 | struct ocfs2_journal_handle *handle, | 101 | handle_t *handle, |
102 | struct inode *parent, | 102 | struct inode *parent, |
103 | struct inode *inode, | 103 | struct inode *inode, |
104 | struct buffer_head *fe_bh, | 104 | struct buffer_head *fe_bh, |
105 | struct ocfs2_alloc_context *data_ac); | 105 | struct ocfs2_alloc_context *data_ac); |
106 | 106 | ||
107 | static int ocfs2_double_lock(struct ocfs2_super *osb, | ||
108 | struct ocfs2_journal_handle *handle, | ||
109 | struct buffer_head **bh1, | ||
110 | struct inode *inode1, | ||
111 | struct buffer_head **bh2, | ||
112 | struct inode *inode2); | ||
113 | |||
114 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 107 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, |
115 | struct ocfs2_journal_handle *handle, | 108 | struct inode **ret_orphan_dir, |
116 | struct inode *inode, | 109 | struct inode *inode, |
117 | char *name, | 110 | char *name, |
118 | struct buffer_head **de_bh); | 111 | struct buffer_head **de_bh); |
119 | 112 | ||
120 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 113 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
121 | struct ocfs2_journal_handle *handle, | 114 | handle_t *handle, |
122 | struct inode *inode, | 115 | struct inode *inode, |
123 | struct ocfs2_dinode *fe, | 116 | struct ocfs2_dinode *fe, |
124 | char *name, | 117 | char *name, |
125 | struct buffer_head *de_bh); | 118 | struct buffer_head *de_bh, |
119 | struct inode *orphan_dir_inode); | ||
126 | 120 | ||
127 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | 121 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, |
128 | struct ocfs2_journal_handle *handle, | 122 | handle_t *handle, |
129 | struct inode *inode, | 123 | struct inode *inode, |
130 | const char *symname); | 124 | const char *symname); |
131 | 125 | ||
132 | static inline int ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 126 | static inline int ocfs2_add_entry(handle_t *handle, |
133 | struct dentry *dentry, | 127 | struct dentry *dentry, |
134 | struct inode *inode, u64 blkno, | 128 | struct inode *inode, u64 blkno, |
135 | struct buffer_head *parent_fe_bh, | 129 | struct buffer_head *parent_fe_bh, |
@@ -165,7 +159,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry, | |||
165 | mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, | 159 | mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, |
166 | dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); | 160 | dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); |
167 | 161 | ||
168 | status = ocfs2_meta_lock(dir, NULL, NULL, 0); | 162 | status = ocfs2_meta_lock(dir, NULL, 0); |
169 | if (status < 0) { | 163 | if (status < 0) { |
170 | if (status != -ENOENT) | 164 | if (status != -ENOENT) |
171 | mlog_errno(status); | 165 | mlog_errno(status); |
@@ -242,7 +236,7 @@ bail: | |||
242 | } | 236 | } |
243 | 237 | ||
244 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, | 238 | static int ocfs2_fill_new_dir(struct ocfs2_super *osb, |
245 | struct ocfs2_journal_handle *handle, | 239 | handle_t *handle, |
246 | struct inode *parent, | 240 | struct inode *parent, |
247 | struct inode *inode, | 241 | struct inode *inode, |
248 | struct buffer_head *fe_bh, | 242 | struct buffer_head *fe_bh, |
@@ -317,7 +311,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
317 | { | 311 | { |
318 | int status = 0; | 312 | int status = 0; |
319 | struct buffer_head *parent_fe_bh = NULL; | 313 | struct buffer_head *parent_fe_bh = NULL; |
320 | struct ocfs2_journal_handle *handle = NULL; | 314 | handle_t *handle = NULL; |
321 | struct ocfs2_super *osb; | 315 | struct ocfs2_super *osb; |
322 | struct ocfs2_dinode *dirfe; | 316 | struct ocfs2_dinode *dirfe; |
323 | struct buffer_head *new_fe_bh = NULL; | 317 | struct buffer_head *new_fe_bh = NULL; |
@@ -333,18 +327,11 @@ static int ocfs2_mknod(struct inode *dir, | |||
333 | /* get our super block */ | 327 | /* get our super block */ |
334 | osb = OCFS2_SB(dir->i_sb); | 328 | osb = OCFS2_SB(dir->i_sb); |
335 | 329 | ||
336 | handle = ocfs2_alloc_handle(osb); | 330 | status = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
337 | if (handle == NULL) { | ||
338 | status = -ENOMEM; | ||
339 | mlog_errno(status); | ||
340 | goto leave; | ||
341 | } | ||
342 | |||
343 | status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | ||
344 | if (status < 0) { | 331 | if (status < 0) { |
345 | if (status != -ENOENT) | 332 | if (status != -ENOENT) |
346 | mlog_errno(status); | 333 | mlog_errno(status); |
347 | goto leave; | 334 | return status; |
348 | } | 335 | } |
349 | 336 | ||
350 | if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) { | 337 | if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) { |
@@ -374,7 +361,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
374 | } | 361 | } |
375 | 362 | ||
376 | /* reserve an inode spot */ | 363 | /* reserve an inode spot */ |
377 | status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); | 364 | status = ocfs2_reserve_new_inode(osb, &inode_ac); |
378 | if (status < 0) { | 365 | if (status < 0) { |
379 | if (status != -ENOSPC) | 366 | if (status != -ENOSPC) |
380 | mlog_errno(status); | 367 | mlog_errno(status); |
@@ -384,7 +371,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
384 | /* are we making a directory? If so, reserve a cluster for his | 371 | /* are we making a directory? If so, reserve a cluster for his |
385 | * 1st extent. */ | 372 | * 1st extent. */ |
386 | if (S_ISDIR(mode)) { | 373 | if (S_ISDIR(mode)) { |
387 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 374 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
388 | if (status < 0) { | 375 | if (status < 0) { |
389 | if (status != -ENOSPC) | 376 | if (status != -ENOSPC) |
390 | mlog_errno(status); | 377 | mlog_errno(status); |
@@ -392,7 +379,7 @@ static int ocfs2_mknod(struct inode *dir, | |||
392 | } | 379 | } |
393 | } | 380 | } |
394 | 381 | ||
395 | handle = ocfs2_start_trans(osb, handle, OCFS2_MKNOD_CREDITS); | 382 | handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS); |
396 | if (IS_ERR(handle)) { | 383 | if (IS_ERR(handle)) { |
397 | status = PTR_ERR(handle); | 384 | status = PTR_ERR(handle); |
398 | handle = NULL; | 385 | handle = NULL; |
@@ -453,7 +440,9 @@ static int ocfs2_mknod(struct inode *dir, | |||
453 | status = 0; | 440 | status = 0; |
454 | leave: | 441 | leave: |
455 | if (handle) | 442 | if (handle) |
456 | ocfs2_commit_trans(handle); | 443 | ocfs2_commit_trans(osb, handle); |
444 | |||
445 | ocfs2_meta_unlock(dir, 1); | ||
457 | 446 | ||
458 | if (status == -ENOSPC) | 447 | if (status == -ENOSPC) |
459 | mlog(0, "Disk is full\n"); | 448 | mlog(0, "Disk is full\n"); |
@@ -487,7 +476,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
487 | dev_t dev, | 476 | dev_t dev, |
488 | struct buffer_head **new_fe_bh, | 477 | struct buffer_head **new_fe_bh, |
489 | struct buffer_head *parent_fe_bh, | 478 | struct buffer_head *parent_fe_bh, |
490 | struct ocfs2_journal_handle *handle, | 479 | handle_t *handle, |
491 | struct inode **ret_inode, | 480 | struct inode **ret_inode, |
492 | struct ocfs2_alloc_context *inode_ac) | 481 | struct ocfs2_alloc_context *inode_ac) |
493 | { | 482 | { |
@@ -653,7 +642,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
653 | struct inode *dir, | 642 | struct inode *dir, |
654 | struct dentry *dentry) | 643 | struct dentry *dentry) |
655 | { | 644 | { |
656 | struct ocfs2_journal_handle *handle = NULL; | 645 | handle_t *handle; |
657 | struct inode *inode = old_dentry->d_inode; | 646 | struct inode *inode = old_dentry->d_inode; |
658 | int err; | 647 | int err; |
659 | struct buffer_head *fe_bh = NULL; | 648 | struct buffer_head *fe_bh = NULL; |
@@ -666,68 +655,60 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
666 | old_dentry->d_name.len, old_dentry->d_name.name, | 655 | old_dentry->d_name.len, old_dentry->d_name.name, |
667 | dentry->d_name.len, dentry->d_name.name); | 656 | dentry->d_name.len, dentry->d_name.name); |
668 | 657 | ||
669 | if (S_ISDIR(inode->i_mode)) { | 658 | if (S_ISDIR(inode->i_mode)) |
670 | err = -EPERM; | 659 | return -EPERM; |
671 | goto bail; | ||
672 | } | ||
673 | |||
674 | handle = ocfs2_alloc_handle(osb); | ||
675 | if (handle == NULL) { | ||
676 | err = -ENOMEM; | ||
677 | goto bail; | ||
678 | } | ||
679 | 660 | ||
680 | err = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | 661 | err = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
681 | if (err < 0) { | 662 | if (err < 0) { |
682 | if (err != -ENOENT) | 663 | if (err != -ENOENT) |
683 | mlog_errno(err); | 664 | mlog_errno(err); |
684 | goto bail; | 665 | return err; |
685 | } | 666 | } |
686 | 667 | ||
687 | if (!dir->i_nlink) { | 668 | if (!dir->i_nlink) { |
688 | err = -ENOENT; | 669 | err = -ENOENT; |
689 | goto bail; | 670 | goto out; |
690 | } | 671 | } |
691 | 672 | ||
692 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, | 673 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, |
693 | dentry->d_name.len); | 674 | dentry->d_name.len); |
694 | if (err) | 675 | if (err) |
695 | goto bail; | 676 | goto out; |
696 | 677 | ||
697 | err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, | 678 | err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, |
698 | dentry->d_name.name, | 679 | dentry->d_name.name, |
699 | dentry->d_name.len, &de_bh); | 680 | dentry->d_name.len, &de_bh); |
700 | if (err < 0) { | 681 | if (err < 0) { |
701 | mlog_errno(err); | 682 | mlog_errno(err); |
702 | goto bail; | 683 | goto out; |
703 | } | 684 | } |
704 | 685 | ||
705 | err = ocfs2_meta_lock(inode, handle, &fe_bh, 1); | 686 | err = ocfs2_meta_lock(inode, &fe_bh, 1); |
706 | if (err < 0) { | 687 | if (err < 0) { |
707 | if (err != -ENOENT) | 688 | if (err != -ENOENT) |
708 | mlog_errno(err); | 689 | mlog_errno(err); |
709 | goto bail; | 690 | goto out; |
710 | } | 691 | } |
711 | 692 | ||
712 | fe = (struct ocfs2_dinode *) fe_bh->b_data; | 693 | fe = (struct ocfs2_dinode *) fe_bh->b_data; |
713 | if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { | 694 | if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { |
714 | err = -EMLINK; | 695 | err = -EMLINK; |
715 | goto bail; | 696 | goto out_unlock_inode; |
716 | } | 697 | } |
717 | 698 | ||
718 | handle = ocfs2_start_trans(osb, handle, OCFS2_LINK_CREDITS); | 699 | handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS); |
719 | if (IS_ERR(handle)) { | 700 | if (IS_ERR(handle)) { |
720 | err = PTR_ERR(handle); | 701 | err = PTR_ERR(handle); |
721 | handle = NULL; | 702 | handle = NULL; |
722 | mlog_errno(err); | 703 | mlog_errno(err); |
723 | goto bail; | 704 | goto out_unlock_inode; |
724 | } | 705 | } |
725 | 706 | ||
726 | err = ocfs2_journal_access(handle, inode, fe_bh, | 707 | err = ocfs2_journal_access(handle, inode, fe_bh, |
727 | OCFS2_JOURNAL_ACCESS_WRITE); | 708 | OCFS2_JOURNAL_ACCESS_WRITE); |
728 | if (err < 0) { | 709 | if (err < 0) { |
729 | mlog_errno(err); | 710 | mlog_errno(err); |
730 | goto bail; | 711 | goto out_commit; |
731 | } | 712 | } |
732 | 713 | ||
733 | inc_nlink(inode); | 714 | inc_nlink(inode); |
@@ -741,7 +722,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
741 | le16_add_cpu(&fe->i_links_count, -1); | 722 | le16_add_cpu(&fe->i_links_count, -1); |
742 | drop_nlink(inode); | 723 | drop_nlink(inode); |
743 | mlog_errno(err); | 724 | mlog_errno(err); |
744 | goto bail; | 725 | goto out_commit; |
745 | } | 726 | } |
746 | 727 | ||
747 | err = ocfs2_add_entry(handle, dentry, inode, | 728 | err = ocfs2_add_entry(handle, dentry, inode, |
@@ -751,21 +732,27 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
751 | le16_add_cpu(&fe->i_links_count, -1); | 732 | le16_add_cpu(&fe->i_links_count, -1); |
752 | drop_nlink(inode); | 733 | drop_nlink(inode); |
753 | mlog_errno(err); | 734 | mlog_errno(err); |
754 | goto bail; | 735 | goto out_commit; |
755 | } | 736 | } |
756 | 737 | ||
757 | err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); | 738 | err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); |
758 | if (err) { | 739 | if (err) { |
759 | mlog_errno(err); | 740 | mlog_errno(err); |
760 | goto bail; | 741 | goto out_commit; |
761 | } | 742 | } |
762 | 743 | ||
763 | atomic_inc(&inode->i_count); | 744 | atomic_inc(&inode->i_count); |
764 | dentry->d_op = &ocfs2_dentry_ops; | 745 | dentry->d_op = &ocfs2_dentry_ops; |
765 | d_instantiate(dentry, inode); | 746 | d_instantiate(dentry, inode); |
766 | bail: | 747 | |
767 | if (handle) | 748 | out_commit: |
768 | ocfs2_commit_trans(handle); | 749 | ocfs2_commit_trans(osb, handle); |
750 | out_unlock_inode: | ||
751 | ocfs2_meta_unlock(inode, 1); | ||
752 | |||
753 | out: | ||
754 | ocfs2_meta_unlock(dir, 1); | ||
755 | |||
769 | if (de_bh) | 756 | if (de_bh) |
770 | brelse(de_bh); | 757 | brelse(de_bh); |
771 | if (fe_bh) | 758 | if (fe_bh) |
@@ -812,13 +799,15 @@ static int ocfs2_unlink(struct inode *dir, | |||
812 | struct dentry *dentry) | 799 | struct dentry *dentry) |
813 | { | 800 | { |
814 | int status; | 801 | int status; |
802 | int child_locked = 0; | ||
815 | struct inode *inode = dentry->d_inode; | 803 | struct inode *inode = dentry->d_inode; |
804 | struct inode *orphan_dir = NULL; | ||
816 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 805 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
817 | u64 blkno; | 806 | u64 blkno; |
818 | struct ocfs2_dinode *fe = NULL; | 807 | struct ocfs2_dinode *fe = NULL; |
819 | struct buffer_head *fe_bh = NULL; | 808 | struct buffer_head *fe_bh = NULL; |
820 | struct buffer_head *parent_node_bh = NULL; | 809 | struct buffer_head *parent_node_bh = NULL; |
821 | struct ocfs2_journal_handle *handle = NULL; | 810 | handle_t *handle = NULL; |
822 | struct ocfs2_dir_entry *dirent = NULL; | 811 | struct ocfs2_dir_entry *dirent = NULL; |
823 | struct buffer_head *dirent_bh = NULL; | 812 | struct buffer_head *dirent_bh = NULL; |
824 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; | 813 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
@@ -833,22 +822,14 @@ static int ocfs2_unlink(struct inode *dir, | |||
833 | 822 | ||
834 | if (inode == osb->root_inode) { | 823 | if (inode == osb->root_inode) { |
835 | mlog(0, "Cannot delete the root directory\n"); | 824 | mlog(0, "Cannot delete the root directory\n"); |
836 | status = -EPERM; | 825 | return -EPERM; |
837 | goto leave; | ||
838 | } | 826 | } |
839 | 827 | ||
840 | handle = ocfs2_alloc_handle(osb); | 828 | status = ocfs2_meta_lock(dir, &parent_node_bh, 1); |
841 | if (handle == NULL) { | ||
842 | status = -ENOMEM; | ||
843 | mlog_errno(status); | ||
844 | goto leave; | ||
845 | } | ||
846 | |||
847 | status = ocfs2_meta_lock(dir, handle, &parent_node_bh, 1); | ||
848 | if (status < 0) { | 829 | if (status < 0) { |
849 | if (status != -ENOENT) | 830 | if (status != -ENOENT) |
850 | mlog_errno(status); | 831 | mlog_errno(status); |
851 | goto leave; | 832 | return status; |
852 | } | 833 | } |
853 | 834 | ||
854 | status = ocfs2_find_files_on_disk(dentry->d_name.name, | 835 | status = ocfs2_find_files_on_disk(dentry->d_name.name, |
@@ -869,12 +850,13 @@ static int ocfs2_unlink(struct inode *dir, | |||
869 | goto leave; | 850 | goto leave; |
870 | } | 851 | } |
871 | 852 | ||
872 | status = ocfs2_meta_lock(inode, handle, &fe_bh, 1); | 853 | status = ocfs2_meta_lock(inode, &fe_bh, 1); |
873 | if (status < 0) { | 854 | if (status < 0) { |
874 | if (status != -ENOENT) | 855 | if (status != -ENOENT) |
875 | mlog_errno(status); | 856 | mlog_errno(status); |
876 | goto leave; | 857 | goto leave; |
877 | } | 858 | } |
859 | child_locked = 1; | ||
878 | 860 | ||
879 | if (S_ISDIR(inode->i_mode)) { | 861 | if (S_ISDIR(inode->i_mode)) { |
880 | if (!ocfs2_empty_dir(inode)) { | 862 | if (!ocfs2_empty_dir(inode)) { |
@@ -895,7 +877,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
895 | } | 877 | } |
896 | 878 | ||
897 | if (inode_is_unlinkable(inode)) { | 879 | if (inode_is_unlinkable(inode)) { |
898 | status = ocfs2_prepare_orphan_dir(osb, handle, inode, | 880 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, inode, |
899 | orphan_name, | 881 | orphan_name, |
900 | &orphan_entry_bh); | 882 | &orphan_entry_bh); |
901 | if (status < 0) { | 883 | if (status < 0) { |
@@ -904,7 +886,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
904 | } | 886 | } |
905 | } | 887 | } |
906 | 888 | ||
907 | handle = ocfs2_start_trans(osb, handle, OCFS2_UNLINK_CREDITS); | 889 | handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS); |
908 | if (IS_ERR(handle)) { | 890 | if (IS_ERR(handle)) { |
909 | status = PTR_ERR(handle); | 891 | status = PTR_ERR(handle); |
910 | handle = NULL; | 892 | handle = NULL; |
@@ -923,7 +905,7 @@ static int ocfs2_unlink(struct inode *dir, | |||
923 | 905 | ||
924 | if (inode_is_unlinkable(inode)) { | 906 | if (inode_is_unlinkable(inode)) { |
925 | status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, | 907 | status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, |
926 | orphan_entry_bh); | 908 | orphan_entry_bh, orphan_dir); |
927 | if (status < 0) { | 909 | if (status < 0) { |
928 | mlog_errno(status); | 910 | mlog_errno(status); |
929 | goto leave; | 911 | goto leave; |
@@ -960,7 +942,19 @@ static int ocfs2_unlink(struct inode *dir, | |||
960 | 942 | ||
961 | leave: | 943 | leave: |
962 | if (handle) | 944 | if (handle) |
963 | ocfs2_commit_trans(handle); | 945 | ocfs2_commit_trans(osb, handle); |
946 | |||
947 | if (child_locked) | ||
948 | ocfs2_meta_unlock(inode, 1); | ||
949 | |||
950 | ocfs2_meta_unlock(dir, 1); | ||
951 | |||
952 | if (orphan_dir) { | ||
953 | /* This was locked for us in ocfs2_prepare_orphan_dir() */ | ||
954 | ocfs2_meta_unlock(orphan_dir, 1); | ||
955 | mutex_unlock(&orphan_dir->i_mutex); | ||
956 | iput(orphan_dir); | ||
957 | } | ||
964 | 958 | ||
965 | if (fe_bh) | 959 | if (fe_bh) |
966 | brelse(fe_bh); | 960 | brelse(fe_bh); |
@@ -984,7 +978,6 @@ leave: | |||
984 | * if they have the same id, then the 1st one is the only one locked. | 978 | * if they have the same id, then the 1st one is the only one locked. |
985 | */ | 979 | */ |
986 | static int ocfs2_double_lock(struct ocfs2_super *osb, | 980 | static int ocfs2_double_lock(struct ocfs2_super *osb, |
987 | struct ocfs2_journal_handle *handle, | ||
988 | struct buffer_head **bh1, | 981 | struct buffer_head **bh1, |
989 | struct inode *inode1, | 982 | struct inode *inode1, |
990 | struct buffer_head **bh2, | 983 | struct buffer_head **bh2, |
@@ -1000,8 +993,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1000 | (unsigned long long)oi1->ip_blkno, | 993 | (unsigned long long)oi1->ip_blkno, |
1001 | (unsigned long long)oi2->ip_blkno); | 994 | (unsigned long long)oi2->ip_blkno); |
1002 | 995 | ||
1003 | BUG_ON(!handle); | ||
1004 | |||
1005 | if (*bh1) | 996 | if (*bh1) |
1006 | *bh1 = NULL; | 997 | *bh1 = NULL; |
1007 | if (*bh2) | 998 | if (*bh2) |
@@ -1021,25 +1012,41 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1021 | inode1 = tmpinode; | 1012 | inode1 = tmpinode; |
1022 | } | 1013 | } |
1023 | /* lock id2 */ | 1014 | /* lock id2 */ |
1024 | status = ocfs2_meta_lock(inode2, handle, bh2, 1); | 1015 | status = ocfs2_meta_lock(inode2, bh2, 1); |
1025 | if (status < 0) { | 1016 | if (status < 0) { |
1026 | if (status != -ENOENT) | 1017 | if (status != -ENOENT) |
1027 | mlog_errno(status); | 1018 | mlog_errno(status); |
1028 | goto bail; | 1019 | goto bail; |
1029 | } | 1020 | } |
1030 | } | 1021 | } |
1022 | |||
1031 | /* lock id1 */ | 1023 | /* lock id1 */ |
1032 | status = ocfs2_meta_lock(inode1, handle, bh1, 1); | 1024 | status = ocfs2_meta_lock(inode1, bh1, 1); |
1033 | if (status < 0) { | 1025 | if (status < 0) { |
1026 | /* | ||
1027 | * An error return must mean that no cluster locks | ||
1028 | * were held on function exit. | ||
1029 | */ | ||
1030 | if (oi1->ip_blkno != oi2->ip_blkno) | ||
1031 | ocfs2_meta_unlock(inode2, 1); | ||
1032 | |||
1034 | if (status != -ENOENT) | 1033 | if (status != -ENOENT) |
1035 | mlog_errno(status); | 1034 | mlog_errno(status); |
1036 | goto bail; | ||
1037 | } | 1035 | } |
1036 | |||
1038 | bail: | 1037 | bail: |
1039 | mlog_exit(status); | 1038 | mlog_exit(status); |
1040 | return status; | 1039 | return status; |
1041 | } | 1040 | } |
1042 | 1041 | ||
1042 | static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2) | ||
1043 | { | ||
1044 | ocfs2_meta_unlock(inode1, 1); | ||
1045 | |||
1046 | if (inode1 != inode2) | ||
1047 | ocfs2_meta_unlock(inode2, 1); | ||
1048 | } | ||
1049 | |||
1043 | #define PARENT_INO(buffer) \ | 1050 | #define PARENT_INO(buffer) \ |
1044 | ((struct ocfs2_dir_entry *) \ | 1051 | ((struct ocfs2_dir_entry *) \ |
1045 | ((char *)buffer + \ | 1052 | ((char *)buffer + \ |
@@ -1050,9 +1057,11 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1050 | struct inode *new_dir, | 1057 | struct inode *new_dir, |
1051 | struct dentry *new_dentry) | 1058 | struct dentry *new_dentry) |
1052 | { | 1059 | { |
1053 | int status = 0, rename_lock = 0; | 1060 | int status = 0, rename_lock = 0, parents_locked = 0; |
1061 | int old_child_locked = 0, new_child_locked = 0; | ||
1054 | struct inode *old_inode = old_dentry->d_inode; | 1062 | struct inode *old_inode = old_dentry->d_inode; |
1055 | struct inode *new_inode = new_dentry->d_inode; | 1063 | struct inode *new_inode = new_dentry->d_inode; |
1064 | struct inode *orphan_dir = NULL; | ||
1056 | struct ocfs2_dinode *newfe = NULL; | 1065 | struct ocfs2_dinode *newfe = NULL; |
1057 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; | 1066 | char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; |
1058 | struct buffer_head *orphan_entry_bh = NULL; | 1067 | struct buffer_head *orphan_entry_bh = NULL; |
@@ -1060,7 +1069,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1060 | struct buffer_head *insert_entry_bh = NULL; | 1069 | struct buffer_head *insert_entry_bh = NULL; |
1061 | struct ocfs2_super *osb = NULL; | 1070 | struct ocfs2_super *osb = NULL; |
1062 | u64 newfe_blkno; | 1071 | u64 newfe_blkno; |
1063 | struct ocfs2_journal_handle *handle = NULL; | 1072 | handle_t *handle = NULL; |
1064 | struct buffer_head *old_dir_bh = NULL; | 1073 | struct buffer_head *old_dir_bh = NULL; |
1065 | struct buffer_head *new_dir_bh = NULL; | 1074 | struct buffer_head *new_dir_bh = NULL; |
1066 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry | 1075 | struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry |
@@ -1105,21 +1114,14 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1105 | rename_lock = 1; | 1114 | rename_lock = 1; |
1106 | } | 1115 | } |
1107 | 1116 | ||
1108 | handle = ocfs2_alloc_handle(osb); | ||
1109 | if (handle == NULL) { | ||
1110 | status = -ENOMEM; | ||
1111 | mlog_errno(status); | ||
1112 | goto bail; | ||
1113 | } | ||
1114 | |||
1115 | /* if old and new are the same, this'll just do one lock. */ | 1117 | /* if old and new are the same, this'll just do one lock. */ |
1116 | status = ocfs2_double_lock(osb, handle, | 1118 | status = ocfs2_double_lock(osb, &old_dir_bh, old_dir, |
1117 | &old_dir_bh, old_dir, | 1119 | &new_dir_bh, new_dir); |
1118 | &new_dir_bh, new_dir); | ||
1119 | if (status < 0) { | 1120 | if (status < 0) { |
1120 | mlog_errno(status); | 1121 | mlog_errno(status); |
1121 | goto bail; | 1122 | goto bail; |
1122 | } | 1123 | } |
1124 | parents_locked = 1; | ||
1123 | 1125 | ||
1124 | /* make sure both dirs have bhs | 1126 | /* make sure both dirs have bhs |
1125 | * get an extra ref on old_dir_bh if old==new */ | 1127 | * get an extra ref on old_dir_bh if old==new */ |
@@ -1140,12 +1142,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1140 | * the vote thread on other nodes won't have to concurrently | 1142 | * the vote thread on other nodes won't have to concurrently |
1141 | * downconvert the inode and the dentry locks. | 1143 | * downconvert the inode and the dentry locks. |
1142 | */ | 1144 | */ |
1143 | status = ocfs2_meta_lock(old_inode, handle, NULL, 1); | 1145 | status = ocfs2_meta_lock(old_inode, NULL, 1); |
1144 | if (status < 0) { | 1146 | if (status < 0) { |
1145 | if (status != -ENOENT) | 1147 | if (status != -ENOENT) |
1146 | mlog_errno(status); | 1148 | mlog_errno(status); |
1147 | goto bail; | 1149 | goto bail; |
1148 | } | 1150 | } |
1151 | old_child_locked = 1; | ||
1149 | 1152 | ||
1150 | status = ocfs2_remote_dentry_delete(old_dentry); | 1153 | status = ocfs2_remote_dentry_delete(old_dentry); |
1151 | if (status < 0) { | 1154 | if (status < 0) { |
@@ -1231,12 +1234,13 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1231 | goto bail; | 1234 | goto bail; |
1232 | } | 1235 | } |
1233 | 1236 | ||
1234 | status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1); | 1237 | status = ocfs2_meta_lock(new_inode, &newfe_bh, 1); |
1235 | if (status < 0) { | 1238 | if (status < 0) { |
1236 | if (status != -ENOENT) | 1239 | if (status != -ENOENT) |
1237 | mlog_errno(status); | 1240 | mlog_errno(status); |
1238 | goto bail; | 1241 | goto bail; |
1239 | } | 1242 | } |
1243 | new_child_locked = 1; | ||
1240 | 1244 | ||
1241 | status = ocfs2_remote_dentry_delete(new_dentry); | 1245 | status = ocfs2_remote_dentry_delete(new_dentry); |
1242 | if (status < 0) { | 1246 | if (status < 0) { |
@@ -1252,7 +1256,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1252 | (unsigned long long)newfe_bh->b_blocknr : 0ULL); | 1256 | (unsigned long long)newfe_bh->b_blocknr : 0ULL); |
1253 | 1257 | ||
1254 | if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { | 1258 | if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { |
1255 | status = ocfs2_prepare_orphan_dir(osb, handle, | 1259 | status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, |
1256 | new_inode, | 1260 | new_inode, |
1257 | orphan_name, | 1261 | orphan_name, |
1258 | &orphan_entry_bh); | 1262 | &orphan_entry_bh); |
@@ -1280,7 +1284,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1280 | } | 1284 | } |
1281 | } | 1285 | } |
1282 | 1286 | ||
1283 | handle = ocfs2_start_trans(osb, handle, OCFS2_RENAME_CREDITS); | 1287 | handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS); |
1284 | if (IS_ERR(handle)) { | 1288 | if (IS_ERR(handle)) { |
1285 | status = PTR_ERR(handle); | 1289 | status = PTR_ERR(handle); |
1286 | handle = NULL; | 1290 | handle = NULL; |
@@ -1307,7 +1311,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1307 | (newfe->i_links_count == cpu_to_le16(1))){ | 1311 | (newfe->i_links_count == cpu_to_le16(1))){ |
1308 | status = ocfs2_orphan_add(osb, handle, new_inode, | 1312 | status = ocfs2_orphan_add(osb, handle, new_inode, |
1309 | newfe, orphan_name, | 1313 | newfe, orphan_name, |
1310 | orphan_entry_bh); | 1314 | orphan_entry_bh, orphan_dir); |
1311 | if (status < 0) { | 1315 | if (status < 0) { |
1312 | mlog_errno(status); | 1316 | mlog_errno(status); |
1313 | goto bail; | 1317 | goto bail; |
@@ -1424,7 +1428,23 @@ bail: | |||
1424 | ocfs2_rename_unlock(osb); | 1428 | ocfs2_rename_unlock(osb); |
1425 | 1429 | ||
1426 | if (handle) | 1430 | if (handle) |
1427 | ocfs2_commit_trans(handle); | 1431 | ocfs2_commit_trans(osb, handle); |
1432 | |||
1433 | if (parents_locked) | ||
1434 | ocfs2_double_unlock(old_dir, new_dir); | ||
1435 | |||
1436 | if (old_child_locked) | ||
1437 | ocfs2_meta_unlock(old_inode, 1); | ||
1438 | |||
1439 | if (new_child_locked) | ||
1440 | ocfs2_meta_unlock(new_inode, 1); | ||
1441 | |||
1442 | if (orphan_dir) { | ||
1443 | /* This was locked for us in ocfs2_prepare_orphan_dir() */ | ||
1444 | ocfs2_meta_unlock(orphan_dir, 1); | ||
1445 | mutex_unlock(&orphan_dir->i_mutex); | ||
1446 | iput(orphan_dir); | ||
1447 | } | ||
1428 | 1448 | ||
1429 | if (new_inode) | 1449 | if (new_inode) |
1430 | sync_mapping_buffers(old_inode->i_mapping); | 1450 | sync_mapping_buffers(old_inode->i_mapping); |
@@ -1458,7 +1478,7 @@ bail: | |||
1458 | * data, including the null terminator. | 1478 | * data, including the null terminator. |
1459 | */ | 1479 | */ |
1460 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | 1480 | static int ocfs2_create_symlink_data(struct ocfs2_super *osb, |
1461 | struct ocfs2_journal_handle *handle, | 1481 | handle_t *handle, |
1462 | struct inode *inode, | 1482 | struct inode *inode, |
1463 | const char *symname) | 1483 | const char *symname) |
1464 | { | 1484 | { |
@@ -1573,7 +1593,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1573 | struct buffer_head *parent_fe_bh = NULL; | 1593 | struct buffer_head *parent_fe_bh = NULL; |
1574 | struct ocfs2_dinode *fe = NULL; | 1594 | struct ocfs2_dinode *fe = NULL; |
1575 | struct ocfs2_dinode *dirfe; | 1595 | struct ocfs2_dinode *dirfe; |
1576 | struct ocfs2_journal_handle *handle = NULL; | 1596 | handle_t *handle = NULL; |
1577 | struct ocfs2_alloc_context *inode_ac = NULL; | 1597 | struct ocfs2_alloc_context *inode_ac = NULL; |
1578 | struct ocfs2_alloc_context *data_ac = NULL; | 1598 | struct ocfs2_alloc_context *data_ac = NULL; |
1579 | 1599 | ||
@@ -1587,19 +1607,12 @@ static int ocfs2_symlink(struct inode *dir, | |||
1587 | 1607 | ||
1588 | credits = ocfs2_calc_symlink_credits(sb); | 1608 | credits = ocfs2_calc_symlink_credits(sb); |
1589 | 1609 | ||
1590 | handle = ocfs2_alloc_handle(osb); | ||
1591 | if (handle == NULL) { | ||
1592 | status = -ENOMEM; | ||
1593 | mlog_errno(status); | ||
1594 | goto bail; | ||
1595 | } | ||
1596 | |||
1597 | /* lock the parent directory */ | 1610 | /* lock the parent directory */ |
1598 | status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); | 1611 | status = ocfs2_meta_lock(dir, &parent_fe_bh, 1); |
1599 | if (status < 0) { | 1612 | if (status < 0) { |
1600 | if (status != -ENOENT) | 1613 | if (status != -ENOENT) |
1601 | mlog_errno(status); | 1614 | mlog_errno(status); |
1602 | goto bail; | 1615 | return status; |
1603 | } | 1616 | } |
1604 | 1617 | ||
1605 | dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; | 1618 | dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; |
@@ -1622,7 +1635,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1622 | goto bail; | 1635 | goto bail; |
1623 | } | 1636 | } |
1624 | 1637 | ||
1625 | status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); | 1638 | status = ocfs2_reserve_new_inode(osb, &inode_ac); |
1626 | if (status < 0) { | 1639 | if (status < 0) { |
1627 | if (status != -ENOSPC) | 1640 | if (status != -ENOSPC) |
1628 | mlog_errno(status); | 1641 | mlog_errno(status); |
@@ -1631,7 +1644,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1631 | 1644 | ||
1632 | /* don't reserve bitmap space for fast symlinks. */ | 1645 | /* don't reserve bitmap space for fast symlinks. */ |
1633 | if (l > ocfs2_fast_symlink_chars(sb)) { | 1646 | if (l > ocfs2_fast_symlink_chars(sb)) { |
1634 | status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); | 1647 | status = ocfs2_reserve_clusters(osb, 1, &data_ac); |
1635 | if (status < 0) { | 1648 | if (status < 0) { |
1636 | if (status != -ENOSPC) | 1649 | if (status != -ENOSPC) |
1637 | mlog_errno(status); | 1650 | mlog_errno(status); |
@@ -1639,7 +1652,7 @@ static int ocfs2_symlink(struct inode *dir, | |||
1639 | } | 1652 | } |
1640 | } | 1653 | } |
1641 | 1654 | ||
1642 | handle = ocfs2_start_trans(osb, handle, credits); | 1655 | handle = ocfs2_start_trans(osb, credits); |
1643 | if (IS_ERR(handle)) { | 1656 | if (IS_ERR(handle)) { |
1644 | status = PTR_ERR(handle); | 1657 | status = PTR_ERR(handle); |
1645 | handle = NULL; | 1658 | handle = NULL; |
@@ -1717,7 +1730,10 @@ static int ocfs2_symlink(struct inode *dir, | |||
1717 | d_instantiate(dentry, inode); | 1730 | d_instantiate(dentry, inode); |
1718 | bail: | 1731 | bail: |
1719 | if (handle) | 1732 | if (handle) |
1720 | ocfs2_commit_trans(handle); | 1733 | ocfs2_commit_trans(osb, handle); |
1734 | |||
1735 | ocfs2_meta_unlock(dir, 1); | ||
1736 | |||
1721 | if (new_fe_bh) | 1737 | if (new_fe_bh) |
1722 | brelse(new_fe_bh); | 1738 | brelse(new_fe_bh); |
1723 | if (parent_fe_bh) | 1739 | if (parent_fe_bh) |
@@ -1768,7 +1784,7 @@ int ocfs2_check_dir_entry(struct inode * dir, | |||
1768 | * If you pass me insert_bh, I'll skip the search of the other dir | 1784 | * If you pass me insert_bh, I'll skip the search of the other dir |
1769 | * blocks and put the record in there. | 1785 | * blocks and put the record in there. |
1770 | */ | 1786 | */ |
1771 | static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, | 1787 | static int __ocfs2_add_entry(handle_t *handle, |
1772 | struct inode *dir, | 1788 | struct inode *dir, |
1773 | const char *name, int namelen, | 1789 | const char *name, int namelen, |
1774 | struct inode *inode, u64 blkno, | 1790 | struct inode *inode, u64 blkno, |
@@ -1854,7 +1870,7 @@ bail: | |||
1854 | * ocfs2_delete_entry deletes a directory entry by merging it with the | 1870 | * ocfs2_delete_entry deletes a directory entry by merging it with the |
1855 | * previous entry | 1871 | * previous entry |
1856 | */ | 1872 | */ |
1857 | static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, | 1873 | static int ocfs2_delete_entry(handle_t *handle, |
1858 | struct inode *dir, | 1874 | struct inode *dir, |
1859 | struct ocfs2_dir_entry *de_del, | 1875 | struct ocfs2_dir_entry *de_del, |
1860 | struct buffer_head *bh) | 1876 | struct buffer_head *bh) |
@@ -2085,19 +2101,19 @@ bail: | |||
2085 | } | 2101 | } |
2086 | 2102 | ||
2087 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | 2103 | static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, |
2088 | struct ocfs2_journal_handle *handle, | 2104 | struct inode **ret_orphan_dir, |
2089 | struct inode *inode, | 2105 | struct inode *inode, |
2090 | char *name, | 2106 | char *name, |
2091 | struct buffer_head **de_bh) | 2107 | struct buffer_head **de_bh) |
2092 | { | 2108 | { |
2093 | struct inode *orphan_dir_inode = NULL; | 2109 | struct inode *orphan_dir_inode; |
2094 | struct buffer_head *orphan_dir_bh = NULL; | 2110 | struct buffer_head *orphan_dir_bh = NULL; |
2095 | int status = 0; | 2111 | int status = 0; |
2096 | 2112 | ||
2097 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); | 2113 | status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); |
2098 | if (status < 0) { | 2114 | if (status < 0) { |
2099 | mlog_errno(status); | 2115 | mlog_errno(status); |
2100 | goto leave; | 2116 | return status; |
2101 | } | 2117 | } |
2102 | 2118 | ||
2103 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | 2119 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, |
@@ -2106,11 +2122,12 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | |||
2106 | if (!orphan_dir_inode) { | 2122 | if (!orphan_dir_inode) { |
2107 | status = -ENOENT; | 2123 | status = -ENOENT; |
2108 | mlog_errno(status); | 2124 | mlog_errno(status); |
2109 | goto leave; | 2125 | return status; |
2110 | } | 2126 | } |
2111 | 2127 | ||
2112 | ocfs2_handle_add_inode(handle, orphan_dir_inode); | 2128 | mutex_lock(&orphan_dir_inode->i_mutex); |
2113 | status = ocfs2_meta_lock(orphan_dir_inode, handle, &orphan_dir_bh, 1); | 2129 | |
2130 | status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1); | ||
2114 | if (status < 0) { | 2131 | if (status < 0) { |
2115 | mlog_errno(status); | 2132 | mlog_errno(status); |
2116 | goto leave; | 2133 | goto leave; |
@@ -2120,13 +2137,19 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, | |||
2120 | orphan_dir_bh, name, | 2137 | orphan_dir_bh, name, |
2121 | OCFS2_ORPHAN_NAMELEN, de_bh); | 2138 | OCFS2_ORPHAN_NAMELEN, de_bh); |
2122 | if (status < 0) { | 2139 | if (status < 0) { |
2140 | ocfs2_meta_unlock(orphan_dir_inode, 1); | ||
2141 | |||
2123 | mlog_errno(status); | 2142 | mlog_errno(status); |
2124 | goto leave; | 2143 | goto leave; |
2125 | } | 2144 | } |
2126 | 2145 | ||
2146 | *ret_orphan_dir = orphan_dir_inode; | ||
2147 | |||
2127 | leave: | 2148 | leave: |
2128 | if (orphan_dir_inode) | 2149 | if (status) { |
2150 | mutex_unlock(&orphan_dir_inode->i_mutex); | ||
2129 | iput(orphan_dir_inode); | 2151 | iput(orphan_dir_inode); |
2152 | } | ||
2130 | 2153 | ||
2131 | if (orphan_dir_bh) | 2154 | if (orphan_dir_bh) |
2132 | brelse(orphan_dir_bh); | 2155 | brelse(orphan_dir_bh); |
@@ -2136,28 +2159,19 @@ leave: | |||
2136 | } | 2159 | } |
2137 | 2160 | ||
2138 | static int ocfs2_orphan_add(struct ocfs2_super *osb, | 2161 | static int ocfs2_orphan_add(struct ocfs2_super *osb, |
2139 | struct ocfs2_journal_handle *handle, | 2162 | handle_t *handle, |
2140 | struct inode *inode, | 2163 | struct inode *inode, |
2141 | struct ocfs2_dinode *fe, | 2164 | struct ocfs2_dinode *fe, |
2142 | char *name, | 2165 | char *name, |
2143 | struct buffer_head *de_bh) | 2166 | struct buffer_head *de_bh, |
2167 | struct inode *orphan_dir_inode) | ||
2144 | { | 2168 | { |
2145 | struct inode *orphan_dir_inode = NULL; | ||
2146 | struct buffer_head *orphan_dir_bh = NULL; | 2169 | struct buffer_head *orphan_dir_bh = NULL; |
2147 | int status = 0; | 2170 | int status = 0; |
2148 | struct ocfs2_dinode *orphan_fe; | 2171 | struct ocfs2_dinode *orphan_fe; |
2149 | 2172 | ||
2150 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); | 2173 | mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); |
2151 | 2174 | ||
2152 | orphan_dir_inode = ocfs2_get_system_file_inode(osb, | ||
2153 | ORPHAN_DIR_SYSTEM_INODE, | ||
2154 | osb->slot_num); | ||
2155 | if (!orphan_dir_inode) { | ||
2156 | status = -ENOENT; | ||
2157 | mlog_errno(status); | ||
2158 | goto leave; | ||
2159 | } | ||
2160 | |||
2161 | status = ocfs2_read_block(osb, | 2175 | status = ocfs2_read_block(osb, |
2162 | OCFS2_I(orphan_dir_inode)->ip_blkno, | 2176 | OCFS2_I(orphan_dir_inode)->ip_blkno, |
2163 | &orphan_dir_bh, OCFS2_BH_CACHED, | 2177 | &orphan_dir_bh, OCFS2_BH_CACHED, |
@@ -2209,9 +2223,6 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb, | |||
2209 | (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); | 2223 | (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); |
2210 | 2224 | ||
2211 | leave: | 2225 | leave: |
2212 | if (orphan_dir_inode) | ||
2213 | iput(orphan_dir_inode); | ||
2214 | |||
2215 | if (orphan_dir_bh) | 2226 | if (orphan_dir_bh) |
2216 | brelse(orphan_dir_bh); | 2227 | brelse(orphan_dir_bh); |
2217 | 2228 | ||
@@ -2221,7 +2232,7 @@ leave: | |||
2221 | 2232 | ||
2222 | /* unlike orphan_add, we expect the orphan dir to already be locked here. */ | 2233 | /* unlike orphan_add, we expect the orphan dir to already be locked here. */ |
2223 | int ocfs2_orphan_del(struct ocfs2_super *osb, | 2234 | int ocfs2_orphan_del(struct ocfs2_super *osb, |
2224 | struct ocfs2_journal_handle *handle, | 2235 | handle_t *handle, |
2225 | struct inode *orphan_dir_inode, | 2236 | struct inode *orphan_dir_inode, |
2226 | struct inode *inode, | 2237 | struct inode *inode, |
2227 | struct buffer_head *orphan_dir_bh) | 2238 | struct buffer_head *orphan_dir_bh) |
@@ -2300,4 +2311,5 @@ struct inode_operations ocfs2_dir_iops = { | |||
2300 | .rename = ocfs2_rename, | 2311 | .rename = ocfs2_rename, |
2301 | .setattr = ocfs2_setattr, | 2312 | .setattr = ocfs2_setattr, |
2302 | .getattr = ocfs2_getattr, | 2313 | .getattr = ocfs2_getattr, |
2314 | .permission = ocfs2_permission, | ||
2303 | }; | 2315 | }; |
diff --git a/fs/ocfs2/namei.h b/fs/ocfs2/namei.h index deaaa97dbf0b..8425944fcccd 100644 --- a/fs/ocfs2/namei.h +++ b/fs/ocfs2/namei.h | |||
@@ -39,7 +39,7 @@ struct buffer_head *ocfs2_find_entry(const char *name, | |||
39 | struct inode *dir, | 39 | struct inode *dir, |
40 | struct ocfs2_dir_entry **res_dir); | 40 | struct ocfs2_dir_entry **res_dir); |
41 | int ocfs2_orphan_del(struct ocfs2_super *osb, | 41 | int ocfs2_orphan_del(struct ocfs2_super *osb, |
42 | struct ocfs2_journal_handle *handle, | 42 | handle_t *handle, |
43 | struct inode *orphan_dir_inode, | 43 | struct inode *orphan_dir_inode, |
44 | struct inode *inode, | 44 | struct inode *inode, |
45 | struct buffer_head *orphan_dir_bh); | 45 | struct buffer_head *orphan_dir_bh); |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 0462a7f4e21b..b767fd7da6eb 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
35 | #include <linux/kref.h> | 35 | #include <linux/kref.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/jbd.h> | ||
37 | 38 | ||
38 | #include "cluster/nodemanager.h" | 39 | #include "cluster/nodemanager.h" |
39 | #include "cluster/heartbeat.h" | 40 | #include "cluster/heartbeat.h" |
@@ -179,9 +180,9 @@ enum ocfs2_mount_options | |||
179 | #define OCFS2_OSB_SOFT_RO 0x0001 | 180 | #define OCFS2_OSB_SOFT_RO 0x0001 |
180 | #define OCFS2_OSB_HARD_RO 0x0002 | 181 | #define OCFS2_OSB_HARD_RO 0x0002 |
181 | #define OCFS2_OSB_ERROR_FS 0x0004 | 182 | #define OCFS2_OSB_ERROR_FS 0x0004 |
183 | #define OCFS2_DEFAULT_ATIME_QUANTUM 60 | ||
182 | 184 | ||
183 | struct ocfs2_journal; | 185 | struct ocfs2_journal; |
184 | struct ocfs2_journal_handle; | ||
185 | struct ocfs2_super | 186 | struct ocfs2_super |
186 | { | 187 | { |
187 | struct task_struct *commit_task; | 188 | struct task_struct *commit_task; |
@@ -218,6 +219,7 @@ struct ocfs2_super | |||
218 | unsigned long osb_flags; | 219 | unsigned long osb_flags; |
219 | 220 | ||
220 | unsigned long s_mount_opt; | 221 | unsigned long s_mount_opt; |
222 | unsigned int s_atime_quantum; | ||
221 | 223 | ||
222 | u16 max_slots; | 224 | u16 max_slots; |
223 | s16 node_num; | 225 | s16 node_num; |
@@ -283,7 +285,7 @@ struct ocfs2_super | |||
283 | /* Truncate log info */ | 285 | /* Truncate log info */ |
284 | struct inode *osb_tl_inode; | 286 | struct inode *osb_tl_inode; |
285 | struct buffer_head *osb_tl_bh; | 287 | struct buffer_head *osb_tl_bh; |
286 | struct work_struct osb_truncate_log_wq; | 288 | struct delayed_work osb_truncate_log_wq; |
287 | 289 | ||
288 | struct ocfs2_node_map osb_recovering_orphan_dirs; | 290 | struct ocfs2_node_map osb_recovering_orphan_dirs; |
289 | unsigned int *osb_orphan_wipes; | 291 | unsigned int *osb_orphan_wipes; |
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 9d91e66f51a9..000d71cca6c5 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -49,7 +49,7 @@ | |||
49 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); | 49 | static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); |
50 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); | 50 | static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); |
51 | static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); | 51 | static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); |
52 | static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, | 52 | static int ocfs2_block_group_fill(handle_t *handle, |
53 | struct inode *alloc_inode, | 53 | struct inode *alloc_inode, |
54 | struct buffer_head *bg_bh, | 54 | struct buffer_head *bg_bh, |
55 | u64 group_blkno, | 55 | u64 group_blkno, |
@@ -59,9 +59,6 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
59 | struct inode *alloc_inode, | 59 | struct inode *alloc_inode, |
60 | struct buffer_head *bh); | 60 | struct buffer_head *bh); |
61 | 61 | ||
62 | static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, | ||
63 | struct ocfs2_alloc_context *ac); | ||
64 | |||
65 | static int ocfs2_cluster_group_search(struct inode *inode, | 62 | static int ocfs2_cluster_group_search(struct inode *inode, |
66 | struct buffer_head *group_bh, | 63 | struct buffer_head *group_bh, |
67 | u32 bits_wanted, u32 min_bits, | 64 | u32 bits_wanted, u32 min_bits, |
@@ -72,6 +69,7 @@ static int ocfs2_block_group_search(struct inode *inode, | |||
72 | u16 *bit_off, u16 *bits_found); | 69 | u16 *bit_off, u16 *bits_found); |
73 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | 70 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, |
74 | struct ocfs2_alloc_context *ac, | 71 | struct ocfs2_alloc_context *ac, |
72 | handle_t *handle, | ||
75 | u32 bits_wanted, | 73 | u32 bits_wanted, |
76 | u32 min_bits, | 74 | u32 min_bits, |
77 | u16 *bit_off, | 75 | u16 *bit_off, |
@@ -79,20 +77,20 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
79 | u64 *bg_blkno); | 77 | u64 *bg_blkno); |
80 | static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, | 78 | static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, |
81 | int nr); | 79 | int nr); |
82 | static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, | 80 | static inline int ocfs2_block_group_set_bits(handle_t *handle, |
83 | struct inode *alloc_inode, | 81 | struct inode *alloc_inode, |
84 | struct ocfs2_group_desc *bg, | 82 | struct ocfs2_group_desc *bg, |
85 | struct buffer_head *group_bh, | 83 | struct buffer_head *group_bh, |
86 | unsigned int bit_off, | 84 | unsigned int bit_off, |
87 | unsigned int num_bits); | 85 | unsigned int num_bits); |
88 | static inline int ocfs2_block_group_clear_bits(struct ocfs2_journal_handle *handle, | 86 | static inline int ocfs2_block_group_clear_bits(handle_t *handle, |
89 | struct inode *alloc_inode, | 87 | struct inode *alloc_inode, |
90 | struct ocfs2_group_desc *bg, | 88 | struct ocfs2_group_desc *bg, |
91 | struct buffer_head *group_bh, | 89 | struct buffer_head *group_bh, |
92 | unsigned int bit_off, | 90 | unsigned int bit_off, |
93 | unsigned int num_bits); | 91 | unsigned int num_bits); |
94 | 92 | ||
95 | static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle, | 93 | static int ocfs2_relink_block_group(handle_t *handle, |
96 | struct inode *alloc_inode, | 94 | struct inode *alloc_inode, |
97 | struct buffer_head *fe_bh, | 95 | struct buffer_head *fe_bh, |
98 | struct buffer_head *bg_bh, | 96 | struct buffer_head *bg_bh, |
@@ -100,7 +98,7 @@ static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle, | |||
100 | u16 chain); | 98 | u16 chain); |
101 | static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg, | 99 | static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg, |
102 | u32 wanted); | 100 | u32 wanted); |
103 | static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle, | 101 | static int ocfs2_free_suballoc_bits(handle_t *handle, |
104 | struct inode *alloc_inode, | 102 | struct inode *alloc_inode, |
105 | struct buffer_head *alloc_bh, | 103 | struct buffer_head *alloc_bh, |
106 | unsigned int start_bit, | 104 | unsigned int start_bit, |
@@ -120,8 +118,16 @@ static inline void ocfs2_block_to_cluster_group(struct inode *inode, | |||
120 | 118 | ||
121 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) | 119 | void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) |
122 | { | 120 | { |
123 | if (ac->ac_inode) | 121 | struct inode *inode = ac->ac_inode; |
124 | iput(ac->ac_inode); | 122 | |
123 | if (inode) { | ||
124 | if (ac->ac_which != OCFS2_AC_USE_LOCAL) | ||
125 | ocfs2_meta_unlock(inode, 1); | ||
126 | |||
127 | mutex_unlock(&inode->i_mutex); | ||
128 | |||
129 | iput(inode); | ||
130 | } | ||
125 | if (ac->ac_bh) | 131 | if (ac->ac_bh) |
126 | brelse(ac->ac_bh); | 132 | brelse(ac->ac_bh); |
127 | kfree(ac); | 133 | kfree(ac); |
@@ -190,7 +196,7 @@ static int ocfs2_check_group_descriptor(struct super_block *sb, | |||
190 | return 0; | 196 | return 0; |
191 | } | 197 | } |
192 | 198 | ||
193 | static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, | 199 | static int ocfs2_block_group_fill(handle_t *handle, |
194 | struct inode *alloc_inode, | 200 | struct inode *alloc_inode, |
195 | struct buffer_head *bg_bh, | 201 | struct buffer_head *bg_bh, |
196 | u64 group_blkno, | 202 | u64 group_blkno, |
@@ -273,7 +279,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
273 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data; | 279 | struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data; |
274 | struct ocfs2_chain_list *cl; | 280 | struct ocfs2_chain_list *cl; |
275 | struct ocfs2_alloc_context *ac = NULL; | 281 | struct ocfs2_alloc_context *ac = NULL; |
276 | struct ocfs2_journal_handle *handle = NULL; | 282 | handle_t *handle = NULL; |
277 | u32 bit_off, num_bits; | 283 | u32 bit_off, num_bits; |
278 | u16 alloc_rec; | 284 | u16 alloc_rec; |
279 | u64 bg_blkno; | 285 | u64 bg_blkno; |
@@ -284,16 +290,8 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
284 | 290 | ||
285 | mlog_entry_void(); | 291 | mlog_entry_void(); |
286 | 292 | ||
287 | handle = ocfs2_alloc_handle(osb); | ||
288 | if (!handle) { | ||
289 | status = -ENOMEM; | ||
290 | mlog_errno(status); | ||
291 | goto bail; | ||
292 | } | ||
293 | |||
294 | cl = &fe->id2.i_chain; | 293 | cl = &fe->id2.i_chain; |
295 | status = ocfs2_reserve_clusters(osb, | 294 | status = ocfs2_reserve_clusters(osb, |
296 | handle, | ||
297 | le16_to_cpu(cl->cl_cpg), | 295 | le16_to_cpu(cl->cl_cpg), |
298 | &ac); | 296 | &ac); |
299 | if (status < 0) { | 297 | if (status < 0) { |
@@ -304,7 +302,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
304 | 302 | ||
305 | credits = ocfs2_calc_group_alloc_credits(osb->sb, | 303 | credits = ocfs2_calc_group_alloc_credits(osb->sb, |
306 | le16_to_cpu(cl->cl_cpg)); | 304 | le16_to_cpu(cl->cl_cpg)); |
307 | handle = ocfs2_start_trans(osb, handle, credits); | 305 | handle = ocfs2_start_trans(osb, credits); |
308 | if (IS_ERR(handle)) { | 306 | if (IS_ERR(handle)) { |
309 | status = PTR_ERR(handle); | 307 | status = PTR_ERR(handle); |
310 | handle = NULL; | 308 | handle = NULL; |
@@ -389,7 +387,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb, | |||
389 | status = 0; | 387 | status = 0; |
390 | bail: | 388 | bail: |
391 | if (handle) | 389 | if (handle) |
392 | ocfs2_commit_trans(handle); | 390 | ocfs2_commit_trans(osb, handle); |
393 | 391 | ||
394 | if (ac) | 392 | if (ac) |
395 | ocfs2_free_alloc_context(ac); | 393 | ocfs2_free_alloc_context(ac); |
@@ -402,27 +400,38 @@ bail: | |||
402 | } | 400 | } |
403 | 401 | ||
404 | static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, | 402 | static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, |
405 | struct ocfs2_alloc_context *ac) | 403 | struct ocfs2_alloc_context *ac, |
404 | int type, | ||
405 | u32 slot) | ||
406 | { | 406 | { |
407 | int status; | 407 | int status; |
408 | u32 bits_wanted = ac->ac_bits_wanted; | 408 | u32 bits_wanted = ac->ac_bits_wanted; |
409 | struct inode *alloc_inode = ac->ac_inode; | 409 | struct inode *alloc_inode; |
410 | struct buffer_head *bh = NULL; | 410 | struct buffer_head *bh = NULL; |
411 | struct ocfs2_journal_handle *handle = ac->ac_handle; | ||
412 | struct ocfs2_dinode *fe; | 411 | struct ocfs2_dinode *fe; |
413 | u32 free_bits; | 412 | u32 free_bits; |
414 | 413 | ||
415 | mlog_entry_void(); | 414 | mlog_entry_void(); |
416 | 415 | ||
417 | BUG_ON(handle->flags & OCFS2_HANDLE_STARTED); | 416 | alloc_inode = ocfs2_get_system_file_inode(osb, type, slot); |
417 | if (!alloc_inode) { | ||
418 | mlog_errno(-EINVAL); | ||
419 | return -EINVAL; | ||
420 | } | ||
418 | 421 | ||
419 | ocfs2_handle_add_inode(handle, alloc_inode); | 422 | mutex_lock(&alloc_inode->i_mutex); |
420 | status = ocfs2_meta_lock(alloc_inode, handle, &bh, 1); | 423 | |
424 | status = ocfs2_meta_lock(alloc_inode, &bh, 1); | ||
421 | if (status < 0) { | 425 | if (status < 0) { |
426 | mutex_unlock(&alloc_inode->i_mutex); | ||
427 | iput(alloc_inode); | ||
428 | |||
422 | mlog_errno(status); | 429 | mlog_errno(status); |
423 | goto bail; | 430 | return status; |
424 | } | 431 | } |
425 | 432 | ||
433 | ac->ac_inode = alloc_inode; | ||
434 | |||
426 | fe = (struct ocfs2_dinode *) bh->b_data; | 435 | fe = (struct ocfs2_dinode *) bh->b_data; |
427 | if (!OCFS2_IS_VALID_DINODE(fe)) { | 436 | if (!OCFS2_IS_VALID_DINODE(fe)) { |
428 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); | 437 | OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); |
@@ -473,12 +482,11 @@ bail: | |||
473 | } | 482 | } |
474 | 483 | ||
475 | int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, | 484 | int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, |
476 | struct ocfs2_journal_handle *handle, | ||
477 | struct ocfs2_dinode *fe, | 485 | struct ocfs2_dinode *fe, |
478 | struct ocfs2_alloc_context **ac) | 486 | struct ocfs2_alloc_context **ac) |
479 | { | 487 | { |
480 | int status; | 488 | int status; |
481 | struct inode *alloc_inode = NULL; | 489 | u32 slot; |
482 | 490 | ||
483 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | 491 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
484 | if (!(*ac)) { | 492 | if (!(*ac)) { |
@@ -488,28 +496,18 @@ int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, | |||
488 | } | 496 | } |
489 | 497 | ||
490 | (*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe); | 498 | (*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe); |
491 | (*ac)->ac_handle = handle; | ||
492 | (*ac)->ac_which = OCFS2_AC_USE_META; | 499 | (*ac)->ac_which = OCFS2_AC_USE_META; |
493 | 500 | ||
494 | #ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS | 501 | #ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS |
495 | alloc_inode = ocfs2_get_system_file_inode(osb, | 502 | slot = 0; |
496 | EXTENT_ALLOC_SYSTEM_INODE, | ||
497 | 0); | ||
498 | #else | 503 | #else |
499 | alloc_inode = ocfs2_get_system_file_inode(osb, | 504 | slot = osb->slot_num; |
500 | EXTENT_ALLOC_SYSTEM_INODE, | ||
501 | osb->slot_num); | ||
502 | #endif | 505 | #endif |
503 | if (!alloc_inode) { | ||
504 | status = -ENOMEM; | ||
505 | mlog_errno(status); | ||
506 | goto bail; | ||
507 | } | ||
508 | 506 | ||
509 | (*ac)->ac_inode = igrab(alloc_inode); | ||
510 | (*ac)->ac_group_search = ocfs2_block_group_search; | 507 | (*ac)->ac_group_search = ocfs2_block_group_search; |
511 | 508 | ||
512 | status = ocfs2_reserve_suballoc_bits(osb, (*ac)); | 509 | status = ocfs2_reserve_suballoc_bits(osb, (*ac), |
510 | EXTENT_ALLOC_SYSTEM_INODE, slot); | ||
513 | if (status < 0) { | 511 | if (status < 0) { |
514 | if (status != -ENOSPC) | 512 | if (status != -ENOSPC) |
515 | mlog_errno(status); | 513 | mlog_errno(status); |
@@ -523,19 +521,14 @@ bail: | |||
523 | *ac = NULL; | 521 | *ac = NULL; |
524 | } | 522 | } |
525 | 523 | ||
526 | if (alloc_inode) | ||
527 | iput(alloc_inode); | ||
528 | |||
529 | mlog_exit(status); | 524 | mlog_exit(status); |
530 | return status; | 525 | return status; |
531 | } | 526 | } |
532 | 527 | ||
533 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | 528 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, |
534 | struct ocfs2_journal_handle *handle, | ||
535 | struct ocfs2_alloc_context **ac) | 529 | struct ocfs2_alloc_context **ac) |
536 | { | 530 | { |
537 | int status; | 531 | int status; |
538 | struct inode *alloc_inode = NULL; | ||
539 | 532 | ||
540 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | 533 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
541 | if (!(*ac)) { | 534 | if (!(*ac)) { |
@@ -545,22 +538,13 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | |||
545 | } | 538 | } |
546 | 539 | ||
547 | (*ac)->ac_bits_wanted = 1; | 540 | (*ac)->ac_bits_wanted = 1; |
548 | (*ac)->ac_handle = handle; | ||
549 | (*ac)->ac_which = OCFS2_AC_USE_INODE; | 541 | (*ac)->ac_which = OCFS2_AC_USE_INODE; |
550 | 542 | ||
551 | alloc_inode = ocfs2_get_system_file_inode(osb, | ||
552 | INODE_ALLOC_SYSTEM_INODE, | ||
553 | osb->slot_num); | ||
554 | if (!alloc_inode) { | ||
555 | status = -ENOMEM; | ||
556 | mlog_errno(status); | ||
557 | goto bail; | ||
558 | } | ||
559 | |||
560 | (*ac)->ac_inode = igrab(alloc_inode); | ||
561 | (*ac)->ac_group_search = ocfs2_block_group_search; | 543 | (*ac)->ac_group_search = ocfs2_block_group_search; |
562 | 544 | ||
563 | status = ocfs2_reserve_suballoc_bits(osb, *ac); | 545 | status = ocfs2_reserve_suballoc_bits(osb, *ac, |
546 | INODE_ALLOC_SYSTEM_INODE, | ||
547 | osb->slot_num); | ||
564 | if (status < 0) { | 548 | if (status < 0) { |
565 | if (status != -ENOSPC) | 549 | if (status != -ENOSPC) |
566 | mlog_errno(status); | 550 | mlog_errno(status); |
@@ -574,9 +558,6 @@ bail: | |||
574 | *ac = NULL; | 558 | *ac = NULL; |
575 | } | 559 | } |
576 | 560 | ||
577 | if (alloc_inode) | ||
578 | iput(alloc_inode); | ||
579 | |||
580 | mlog_exit(status); | 561 | mlog_exit(status); |
581 | return status; | 562 | return status; |
582 | } | 563 | } |
@@ -588,20 +569,17 @@ int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb, | |||
588 | { | 569 | { |
589 | int status; | 570 | int status; |
590 | 571 | ||
591 | ac->ac_inode = ocfs2_get_system_file_inode(osb, | ||
592 | GLOBAL_BITMAP_SYSTEM_INODE, | ||
593 | OCFS2_INVALID_SLOT); | ||
594 | if (!ac->ac_inode) { | ||
595 | status = -EINVAL; | ||
596 | mlog(ML_ERROR, "Could not get bitmap inode!\n"); | ||
597 | goto bail; | ||
598 | } | ||
599 | ac->ac_which = OCFS2_AC_USE_MAIN; | 572 | ac->ac_which = OCFS2_AC_USE_MAIN; |
600 | ac->ac_group_search = ocfs2_cluster_group_search; | 573 | ac->ac_group_search = ocfs2_cluster_group_search; |
601 | 574 | ||
602 | status = ocfs2_reserve_suballoc_bits(osb, ac); | 575 | status = ocfs2_reserve_suballoc_bits(osb, ac, |
603 | if (status < 0 && status != -ENOSPC) | 576 | GLOBAL_BITMAP_SYSTEM_INODE, |
577 | OCFS2_INVALID_SLOT); | ||
578 | if (status < 0 && status != -ENOSPC) { | ||
604 | mlog_errno(status); | 579 | mlog_errno(status); |
580 | goto bail; | ||
581 | } | ||
582 | |||
605 | bail: | 583 | bail: |
606 | return status; | 584 | return status; |
607 | } | 585 | } |
@@ -610,7 +588,6 @@ bail: | |||
610 | * use so we figure it out for them, but unfortunately this clutters | 588 | * use so we figure it out for them, but unfortunately this clutters |
611 | * things a bit. */ | 589 | * things a bit. */ |
612 | int ocfs2_reserve_clusters(struct ocfs2_super *osb, | 590 | int ocfs2_reserve_clusters(struct ocfs2_super *osb, |
613 | struct ocfs2_journal_handle *handle, | ||
614 | u32 bits_wanted, | 591 | u32 bits_wanted, |
615 | struct ocfs2_alloc_context **ac) | 592 | struct ocfs2_alloc_context **ac) |
616 | { | 593 | { |
@@ -618,8 +595,6 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb, | |||
618 | 595 | ||
619 | mlog_entry_void(); | 596 | mlog_entry_void(); |
620 | 597 | ||
621 | BUG_ON(!handle); | ||
622 | |||
623 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); | 598 | *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); |
624 | if (!(*ac)) { | 599 | if (!(*ac)) { |
625 | status = -ENOMEM; | 600 | status = -ENOMEM; |
@@ -628,12 +603,10 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb, | |||
628 | } | 603 | } |
629 | 604 | ||
630 | (*ac)->ac_bits_wanted = bits_wanted; | 605 | (*ac)->ac_bits_wanted = bits_wanted; |
631 | (*ac)->ac_handle = handle; | ||
632 | 606 | ||
633 | status = -ENOSPC; | 607 | status = -ENOSPC; |
634 | if (ocfs2_alloc_should_use_local(osb, bits_wanted)) { | 608 | if (ocfs2_alloc_should_use_local(osb, bits_wanted)) { |
635 | status = ocfs2_reserve_local_alloc_bits(osb, | 609 | status = ocfs2_reserve_local_alloc_bits(osb, |
636 | handle, | ||
637 | bits_wanted, | 610 | bits_wanted, |
638 | *ac); | 611 | *ac); |
639 | if ((status < 0) && (status != -ENOSPC)) { | 612 | if ((status < 0) && (status != -ENOSPC)) { |
@@ -774,7 +747,7 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb, | |||
774 | return status; | 747 | return status; |
775 | } | 748 | } |
776 | 749 | ||
777 | static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, | 750 | static inline int ocfs2_block_group_set_bits(handle_t *handle, |
778 | struct inode *alloc_inode, | 751 | struct inode *alloc_inode, |
779 | struct ocfs2_group_desc *bg, | 752 | struct ocfs2_group_desc *bg, |
780 | struct buffer_head *group_bh, | 753 | struct buffer_head *group_bh, |
@@ -845,7 +818,7 @@ static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl) | |||
845 | return best; | 818 | return best; |
846 | } | 819 | } |
847 | 820 | ||
848 | static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle, | 821 | static int ocfs2_relink_block_group(handle_t *handle, |
849 | struct inode *alloc_inode, | 822 | struct inode *alloc_inode, |
850 | struct buffer_head *fe_bh, | 823 | struct buffer_head *fe_bh, |
851 | struct buffer_head *bg_bh, | 824 | struct buffer_head *bg_bh, |
@@ -1025,7 +998,7 @@ static int ocfs2_block_group_search(struct inode *inode, | |||
1025 | } | 998 | } |
1026 | 999 | ||
1027 | static int ocfs2_alloc_dinode_update_counts(struct inode *inode, | 1000 | static int ocfs2_alloc_dinode_update_counts(struct inode *inode, |
1028 | struct ocfs2_journal_handle *handle, | 1001 | handle_t *handle, |
1029 | struct buffer_head *di_bh, | 1002 | struct buffer_head *di_bh, |
1030 | u32 num_bits, | 1003 | u32 num_bits, |
1031 | u16 chain) | 1004 | u16 chain) |
@@ -1055,6 +1028,7 @@ out: | |||
1055 | } | 1028 | } |
1056 | 1029 | ||
1057 | static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | 1030 | static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, |
1031 | handle_t *handle, | ||
1058 | u32 bits_wanted, | 1032 | u32 bits_wanted, |
1059 | u32 min_bits, | 1033 | u32 min_bits, |
1060 | u16 *bit_off, | 1034 | u16 *bit_off, |
@@ -1067,7 +1041,6 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
1067 | struct buffer_head *group_bh = NULL; | 1041 | struct buffer_head *group_bh = NULL; |
1068 | struct ocfs2_group_desc *gd; | 1042 | struct ocfs2_group_desc *gd; |
1069 | struct inode *alloc_inode = ac->ac_inode; | 1043 | struct inode *alloc_inode = ac->ac_inode; |
1070 | struct ocfs2_journal_handle *handle = ac->ac_handle; | ||
1071 | 1044 | ||
1072 | ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno, | 1045 | ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno, |
1073 | &group_bh, OCFS2_BH_CACHED, alloc_inode); | 1046 | &group_bh, OCFS2_BH_CACHED, alloc_inode); |
@@ -1115,6 +1088,7 @@ out: | |||
1115 | } | 1088 | } |
1116 | 1089 | ||
1117 | static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | 1090 | static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, |
1091 | handle_t *handle, | ||
1118 | u32 bits_wanted, | 1092 | u32 bits_wanted, |
1119 | u32 min_bits, | 1093 | u32 min_bits, |
1120 | u16 *bit_off, | 1094 | u16 *bit_off, |
@@ -1126,7 +1100,6 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1126 | u16 chain, tmp_bits; | 1100 | u16 chain, tmp_bits; |
1127 | u32 tmp_used; | 1101 | u32 tmp_used; |
1128 | u64 next_group; | 1102 | u64 next_group; |
1129 | struct ocfs2_journal_handle *handle = ac->ac_handle; | ||
1130 | struct inode *alloc_inode = ac->ac_inode; | 1103 | struct inode *alloc_inode = ac->ac_inode; |
1131 | struct buffer_head *group_bh = NULL; | 1104 | struct buffer_head *group_bh = NULL; |
1132 | struct buffer_head *prev_group_bh = NULL; | 1105 | struct buffer_head *prev_group_bh = NULL; |
@@ -1272,6 +1245,7 @@ bail: | |||
1272 | /* will give out up to bits_wanted contiguous bits. */ | 1245 | /* will give out up to bits_wanted contiguous bits. */ |
1273 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | 1246 | static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, |
1274 | struct ocfs2_alloc_context *ac, | 1247 | struct ocfs2_alloc_context *ac, |
1248 | handle_t *handle, | ||
1275 | u32 bits_wanted, | 1249 | u32 bits_wanted, |
1276 | u32 min_bits, | 1250 | u32 min_bits, |
1277 | u16 *bit_off, | 1251 | u16 *bit_off, |
@@ -1313,8 +1287,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
1313 | * by jumping straight to the most recently used | 1287 | * by jumping straight to the most recently used |
1314 | * allocation group. This helps us mantain some | 1288 | * allocation group. This helps us mantain some |
1315 | * contiguousness across allocations. */ | 1289 | * contiguousness across allocations. */ |
1316 | status = ocfs2_search_one_group(ac, bits_wanted, min_bits, | 1290 | status = ocfs2_search_one_group(ac, handle, bits_wanted, |
1317 | bit_off, num_bits, | 1291 | min_bits, bit_off, num_bits, |
1318 | hint_blkno, &bits_left); | 1292 | hint_blkno, &bits_left); |
1319 | if (!status) { | 1293 | if (!status) { |
1320 | /* Be careful to update *bg_blkno here as the | 1294 | /* Be careful to update *bg_blkno here as the |
@@ -1336,7 +1310,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
1336 | ac->ac_chain = victim; | 1310 | ac->ac_chain = victim; |
1337 | ac->ac_allow_chain_relink = 1; | 1311 | ac->ac_allow_chain_relink = 1; |
1338 | 1312 | ||
1339 | status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off, | 1313 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, bit_off, |
1340 | num_bits, bg_blkno, &bits_left); | 1314 | num_bits, bg_blkno, &bits_left); |
1341 | if (!status) | 1315 | if (!status) |
1342 | goto set_hint; | 1316 | goto set_hint; |
@@ -1360,7 +1334,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, | |||
1360 | continue; | 1334 | continue; |
1361 | 1335 | ||
1362 | ac->ac_chain = i; | 1336 | ac->ac_chain = i; |
1363 | status = ocfs2_search_chain(ac, bits_wanted, min_bits, | 1337 | status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, |
1364 | bit_off, num_bits, bg_blkno, | 1338 | bit_off, num_bits, bg_blkno, |
1365 | &bits_left); | 1339 | &bits_left); |
1366 | if (!status) | 1340 | if (!status) |
@@ -1388,7 +1362,7 @@ bail: | |||
1388 | } | 1362 | } |
1389 | 1363 | ||
1390 | int ocfs2_claim_metadata(struct ocfs2_super *osb, | 1364 | int ocfs2_claim_metadata(struct ocfs2_super *osb, |
1391 | struct ocfs2_journal_handle *handle, | 1365 | handle_t *handle, |
1392 | struct ocfs2_alloc_context *ac, | 1366 | struct ocfs2_alloc_context *ac, |
1393 | u32 bits_wanted, | 1367 | u32 bits_wanted, |
1394 | u16 *suballoc_bit_start, | 1368 | u16 *suballoc_bit_start, |
@@ -1401,10 +1375,10 @@ int ocfs2_claim_metadata(struct ocfs2_super *osb, | |||
1401 | BUG_ON(!ac); | 1375 | BUG_ON(!ac); |
1402 | BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted)); | 1376 | BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted)); |
1403 | BUG_ON(ac->ac_which != OCFS2_AC_USE_META); | 1377 | BUG_ON(ac->ac_which != OCFS2_AC_USE_META); |
1404 | BUG_ON(ac->ac_handle != handle); | ||
1405 | 1378 | ||
1406 | status = ocfs2_claim_suballoc_bits(osb, | 1379 | status = ocfs2_claim_suballoc_bits(osb, |
1407 | ac, | 1380 | ac, |
1381 | handle, | ||
1408 | bits_wanted, | 1382 | bits_wanted, |
1409 | 1, | 1383 | 1, |
1410 | suballoc_bit_start, | 1384 | suballoc_bit_start, |
@@ -1425,7 +1399,7 @@ bail: | |||
1425 | } | 1399 | } |
1426 | 1400 | ||
1427 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, | 1401 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, |
1428 | struct ocfs2_journal_handle *handle, | 1402 | handle_t *handle, |
1429 | struct ocfs2_alloc_context *ac, | 1403 | struct ocfs2_alloc_context *ac, |
1430 | u16 *suballoc_bit, | 1404 | u16 *suballoc_bit, |
1431 | u64 *fe_blkno) | 1405 | u64 *fe_blkno) |
@@ -1440,10 +1414,10 @@ int ocfs2_claim_new_inode(struct ocfs2_super *osb, | |||
1440 | BUG_ON(ac->ac_bits_given != 0); | 1414 | BUG_ON(ac->ac_bits_given != 0); |
1441 | BUG_ON(ac->ac_bits_wanted != 1); | 1415 | BUG_ON(ac->ac_bits_wanted != 1); |
1442 | BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); | 1416 | BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); |
1443 | BUG_ON(ac->ac_handle != handle); | ||
1444 | 1417 | ||
1445 | status = ocfs2_claim_suballoc_bits(osb, | 1418 | status = ocfs2_claim_suballoc_bits(osb, |
1446 | ac, | 1419 | ac, |
1420 | handle, | ||
1447 | 1, | 1421 | 1, |
1448 | 1, | 1422 | 1, |
1449 | suballoc_bit, | 1423 | suballoc_bit, |
@@ -1528,7 +1502,7 @@ static inline void ocfs2_block_to_cluster_group(struct inode *inode, | |||
1528 | * of any size. | 1502 | * of any size. |
1529 | */ | 1503 | */ |
1530 | int ocfs2_claim_clusters(struct ocfs2_super *osb, | 1504 | int ocfs2_claim_clusters(struct ocfs2_super *osb, |
1531 | struct ocfs2_journal_handle *handle, | 1505 | handle_t *handle, |
1532 | struct ocfs2_alloc_context *ac, | 1506 | struct ocfs2_alloc_context *ac, |
1533 | u32 min_clusters, | 1507 | u32 min_clusters, |
1534 | u32 *cluster_start, | 1508 | u32 *cluster_start, |
@@ -1546,7 +1520,6 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, | |||
1546 | 1520 | ||
1547 | BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL | 1521 | BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL |
1548 | && ac->ac_which != OCFS2_AC_USE_MAIN); | 1522 | && ac->ac_which != OCFS2_AC_USE_MAIN); |
1549 | BUG_ON(ac->ac_handle != handle); | ||
1550 | 1523 | ||
1551 | if (ac->ac_which == OCFS2_AC_USE_LOCAL) { | 1524 | if (ac->ac_which == OCFS2_AC_USE_LOCAL) { |
1552 | status = ocfs2_claim_local_alloc_bits(osb, | 1525 | status = ocfs2_claim_local_alloc_bits(osb, |
@@ -1572,6 +1545,7 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, | |||
1572 | 1545 | ||
1573 | status = ocfs2_claim_suballoc_bits(osb, | 1546 | status = ocfs2_claim_suballoc_bits(osb, |
1574 | ac, | 1547 | ac, |
1548 | handle, | ||
1575 | bits_wanted, | 1549 | bits_wanted, |
1576 | min_clusters, | 1550 | min_clusters, |
1577 | &bg_bit_off, | 1551 | &bg_bit_off, |
@@ -1598,7 +1572,7 @@ bail: | |||
1598 | return status; | 1572 | return status; |
1599 | } | 1573 | } |
1600 | 1574 | ||
1601 | static inline int ocfs2_block_group_clear_bits(struct ocfs2_journal_handle *handle, | 1575 | static inline int ocfs2_block_group_clear_bits(handle_t *handle, |
1602 | struct inode *alloc_inode, | 1576 | struct inode *alloc_inode, |
1603 | struct ocfs2_group_desc *bg, | 1577 | struct ocfs2_group_desc *bg, |
1604 | struct buffer_head *group_bh, | 1578 | struct buffer_head *group_bh, |
@@ -1653,7 +1627,7 @@ bail: | |||
1653 | /* | 1627 | /* |
1654 | * expects the suballoc inode to already be locked. | 1628 | * expects the suballoc inode to already be locked. |
1655 | */ | 1629 | */ |
1656 | static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle, | 1630 | static int ocfs2_free_suballoc_bits(handle_t *handle, |
1657 | struct inode *alloc_inode, | 1631 | struct inode *alloc_inode, |
1658 | struct buffer_head *alloc_bh, | 1632 | struct buffer_head *alloc_bh, |
1659 | unsigned int start_bit, | 1633 | unsigned int start_bit, |
@@ -1737,7 +1711,7 @@ static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit) | |||
1737 | return group; | 1711 | return group; |
1738 | } | 1712 | } |
1739 | 1713 | ||
1740 | int ocfs2_free_dinode(struct ocfs2_journal_handle *handle, | 1714 | int ocfs2_free_dinode(handle_t *handle, |
1741 | struct inode *inode_alloc_inode, | 1715 | struct inode *inode_alloc_inode, |
1742 | struct buffer_head *inode_alloc_bh, | 1716 | struct buffer_head *inode_alloc_bh, |
1743 | struct ocfs2_dinode *di) | 1717 | struct ocfs2_dinode *di) |
@@ -1750,7 +1724,7 @@ int ocfs2_free_dinode(struct ocfs2_journal_handle *handle, | |||
1750 | inode_alloc_bh, bit, bg_blkno, 1); | 1724 | inode_alloc_bh, bit, bg_blkno, 1); |
1751 | } | 1725 | } |
1752 | 1726 | ||
1753 | int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle, | 1727 | int ocfs2_free_extent_block(handle_t *handle, |
1754 | struct inode *eb_alloc_inode, | 1728 | struct inode *eb_alloc_inode, |
1755 | struct buffer_head *eb_alloc_bh, | 1729 | struct buffer_head *eb_alloc_bh, |
1756 | struct ocfs2_extent_block *eb) | 1730 | struct ocfs2_extent_block *eb) |
@@ -1763,7 +1737,7 @@ int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle, | |||
1763 | bit, bg_blkno, 1); | 1737 | bit, bg_blkno, 1); |
1764 | } | 1738 | } |
1765 | 1739 | ||
1766 | int ocfs2_free_clusters(struct ocfs2_journal_handle *handle, | 1740 | int ocfs2_free_clusters(handle_t *handle, |
1767 | struct inode *bitmap_inode, | 1741 | struct inode *bitmap_inode, |
1768 | struct buffer_head *bitmap_bh, | 1742 | struct buffer_head *bitmap_bh, |
1769 | u64 start_blk, | 1743 | u64 start_blk, |
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index c787838d1052..1a3c94cb9250 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h | |||
@@ -43,7 +43,6 @@ struct ocfs2_alloc_context { | |||
43 | #define OCFS2_AC_USE_INODE 3 | 43 | #define OCFS2_AC_USE_INODE 3 |
44 | #define OCFS2_AC_USE_META 4 | 44 | #define OCFS2_AC_USE_META 4 |
45 | u32 ac_which; | 45 | u32 ac_which; |
46 | struct ocfs2_journal_handle *ac_handle; | ||
47 | 46 | ||
48 | /* these are used by the chain search */ | 47 | /* these are used by the chain search */ |
49 | u16 ac_chain; | 48 | u16 ac_chain; |
@@ -60,45 +59,42 @@ static inline int ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context *ac) | |||
60 | } | 59 | } |
61 | 60 | ||
62 | int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, | 61 | int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, |
63 | struct ocfs2_journal_handle *handle, | ||
64 | struct ocfs2_dinode *fe, | 62 | struct ocfs2_dinode *fe, |
65 | struct ocfs2_alloc_context **ac); | 63 | struct ocfs2_alloc_context **ac); |
66 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, | 64 | int ocfs2_reserve_new_inode(struct ocfs2_super *osb, |
67 | struct ocfs2_journal_handle *handle, | ||
68 | struct ocfs2_alloc_context **ac); | 65 | struct ocfs2_alloc_context **ac); |
69 | int ocfs2_reserve_clusters(struct ocfs2_super *osb, | 66 | int ocfs2_reserve_clusters(struct ocfs2_super *osb, |
70 | struct ocfs2_journal_handle *handle, | ||
71 | u32 bits_wanted, | 67 | u32 bits_wanted, |
72 | struct ocfs2_alloc_context **ac); | 68 | struct ocfs2_alloc_context **ac); |
73 | 69 | ||
74 | int ocfs2_claim_metadata(struct ocfs2_super *osb, | 70 | int ocfs2_claim_metadata(struct ocfs2_super *osb, |
75 | struct ocfs2_journal_handle *handle, | 71 | handle_t *handle, |
76 | struct ocfs2_alloc_context *ac, | 72 | struct ocfs2_alloc_context *ac, |
77 | u32 bits_wanted, | 73 | u32 bits_wanted, |
78 | u16 *suballoc_bit_start, | 74 | u16 *suballoc_bit_start, |
79 | u32 *num_bits, | 75 | u32 *num_bits, |
80 | u64 *blkno_start); | 76 | u64 *blkno_start); |
81 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, | 77 | int ocfs2_claim_new_inode(struct ocfs2_super *osb, |
82 | struct ocfs2_journal_handle *handle, | 78 | handle_t *handle, |
83 | struct ocfs2_alloc_context *ac, | 79 | struct ocfs2_alloc_context *ac, |
84 | u16 *suballoc_bit, | 80 | u16 *suballoc_bit, |
85 | u64 *fe_blkno); | 81 | u64 *fe_blkno); |
86 | int ocfs2_claim_clusters(struct ocfs2_super *osb, | 82 | int ocfs2_claim_clusters(struct ocfs2_super *osb, |
87 | struct ocfs2_journal_handle *handle, | 83 | handle_t *handle, |
88 | struct ocfs2_alloc_context *ac, | 84 | struct ocfs2_alloc_context *ac, |
89 | u32 min_clusters, | 85 | u32 min_clusters, |
90 | u32 *cluster_start, | 86 | u32 *cluster_start, |
91 | u32 *num_clusters); | 87 | u32 *num_clusters); |
92 | 88 | ||
93 | int ocfs2_free_dinode(struct ocfs2_journal_handle *handle, | 89 | int ocfs2_free_dinode(handle_t *handle, |
94 | struct inode *inode_alloc_inode, | 90 | struct inode *inode_alloc_inode, |
95 | struct buffer_head *inode_alloc_bh, | 91 | struct buffer_head *inode_alloc_bh, |
96 | struct ocfs2_dinode *di); | 92 | struct ocfs2_dinode *di); |
97 | int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle, | 93 | int ocfs2_free_extent_block(handle_t *handle, |
98 | struct inode *eb_alloc_inode, | 94 | struct inode *eb_alloc_inode, |
99 | struct buffer_head *eb_alloc_bh, | 95 | struct buffer_head *eb_alloc_bh, |
100 | struct ocfs2_extent_block *eb); | 96 | struct ocfs2_extent_block *eb); |
101 | int ocfs2_free_clusters(struct ocfs2_journal_handle *handle, | 97 | int ocfs2_free_clusters(handle_t *handle, |
102 | struct inode *bitmap_inode, | 98 | struct inode *bitmap_inode, |
103 | struct buffer_head *bitmap_bh, | 99 | struct buffer_head *bitmap_bh, |
104 | u64 start_blk, | 100 | u64 start_blk, |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 76b46ebbb10c..4bf39540e652 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -68,9 +68,7 @@ | |||
68 | 68 | ||
69 | #include "buffer_head_io.h" | 69 | #include "buffer_head_io.h" |
70 | 70 | ||
71 | static kmem_cache_t *ocfs2_inode_cachep = NULL; | 71 | static struct kmem_cache *ocfs2_inode_cachep = NULL; |
72 | |||
73 | kmem_cache_t *ocfs2_lock_cache = NULL; | ||
74 | 72 | ||
75 | /* OCFS2 needs to schedule several differnt types of work which | 73 | /* OCFS2 needs to schedule several differnt types of work which |
76 | * require cluster locking, disk I/O, recovery waits, etc. Since these | 74 | * require cluster locking, disk I/O, recovery waits, etc. Since these |
@@ -141,6 +139,7 @@ enum { | |||
141 | Opt_hb_local, | 139 | Opt_hb_local, |
142 | Opt_data_ordered, | 140 | Opt_data_ordered, |
143 | Opt_data_writeback, | 141 | Opt_data_writeback, |
142 | Opt_atime_quantum, | ||
144 | Opt_err, | 143 | Opt_err, |
145 | }; | 144 | }; |
146 | 145 | ||
@@ -154,6 +153,7 @@ static match_table_t tokens = { | |||
154 | {Opt_hb_local, OCFS2_HB_LOCAL}, | 153 | {Opt_hb_local, OCFS2_HB_LOCAL}, |
155 | {Opt_data_ordered, "data=ordered"}, | 154 | {Opt_data_ordered, "data=ordered"}, |
156 | {Opt_data_writeback, "data=writeback"}, | 155 | {Opt_data_writeback, "data=writeback"}, |
156 | {Opt_atime_quantum, "atime_quantum=%u"}, | ||
157 | {Opt_err, NULL} | 157 | {Opt_err, NULL} |
158 | }; | 158 | }; |
159 | 159 | ||
@@ -303,7 +303,7 @@ static struct inode *ocfs2_alloc_inode(struct super_block *sb) | |||
303 | { | 303 | { |
304 | struct ocfs2_inode_info *oi; | 304 | struct ocfs2_inode_info *oi; |
305 | 305 | ||
306 | oi = kmem_cache_alloc(ocfs2_inode_cachep, SLAB_NOFS); | 306 | oi = kmem_cache_alloc(ocfs2_inode_cachep, GFP_NOFS); |
307 | if (!oi) | 307 | if (!oi) |
308 | return NULL; | 308 | return NULL; |
309 | 309 | ||
@@ -707,6 +707,7 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
707 | while ((p = strsep(&options, ",")) != NULL) { | 707 | while ((p = strsep(&options, ",")) != NULL) { |
708 | int token, option; | 708 | int token, option; |
709 | substring_t args[MAX_OPT_ARGS]; | 709 | substring_t args[MAX_OPT_ARGS]; |
710 | struct ocfs2_super * osb = OCFS2_SB(sb); | ||
710 | 711 | ||
711 | if (!*p) | 712 | if (!*p) |
712 | continue; | 713 | continue; |
@@ -747,6 +748,16 @@ static int ocfs2_parse_options(struct super_block *sb, | |||
747 | case Opt_data_writeback: | 748 | case Opt_data_writeback: |
748 | *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK; | 749 | *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK; |
749 | break; | 750 | break; |
751 | case Opt_atime_quantum: | ||
752 | if (match_int(&args[0], &option)) { | ||
753 | status = 0; | ||
754 | goto bail; | ||
755 | } | ||
756 | if (option >= 0) | ||
757 | osb->s_atime_quantum = option; | ||
758 | else | ||
759 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | ||
760 | break; | ||
750 | default: | 761 | default: |
751 | mlog(ML_ERROR, | 762 | mlog(ML_ERROR, |
752 | "Unrecognized mount option \"%s\" " | 763 | "Unrecognized mount option \"%s\" " |
@@ -867,7 +878,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
867 | goto bail; | 878 | goto bail; |
868 | } | 879 | } |
869 | 880 | ||
870 | status = ocfs2_meta_lock(inode, NULL, &bh, 0); | 881 | status = ocfs2_meta_lock(inode, &bh, 0); |
871 | if (status < 0) { | 882 | if (status < 0) { |
872 | mlog_errno(status); | 883 | mlog_errno(status); |
873 | goto bail; | 884 | goto bail; |
@@ -903,7 +914,7 @@ bail: | |||
903 | } | 914 | } |
904 | 915 | ||
905 | static void ocfs2_inode_init_once(void *data, | 916 | static void ocfs2_inode_init_once(void *data, |
906 | kmem_cache_t *cachep, | 917 | struct kmem_cache *cachep, |
907 | unsigned long flags) | 918 | unsigned long flags) |
908 | { | 919 | { |
909 | struct ocfs2_inode_info *oi = data; | 920 | struct ocfs2_inode_info *oi = data; |
@@ -914,9 +925,7 @@ static void ocfs2_inode_init_once(void *data, | |||
914 | oi->ip_open_count = 0; | 925 | oi->ip_open_count = 0; |
915 | spin_lock_init(&oi->ip_lock); | 926 | spin_lock_init(&oi->ip_lock); |
916 | ocfs2_extent_map_init(&oi->vfs_inode); | 927 | ocfs2_extent_map_init(&oi->vfs_inode); |
917 | INIT_LIST_HEAD(&oi->ip_handle_list); | ||
918 | INIT_LIST_HEAD(&oi->ip_io_markers); | 928 | INIT_LIST_HEAD(&oi->ip_io_markers); |
919 | oi->ip_handle = NULL; | ||
920 | oi->ip_created_trans = 0; | 929 | oi->ip_created_trans = 0; |
921 | oi->ip_last_trans = 0; | 930 | oi->ip_last_trans = 0; |
922 | oi->ip_dir_start_lookup = 0; | 931 | oi->ip_dir_start_lookup = 0; |
@@ -948,14 +957,6 @@ static int ocfs2_initialize_mem_caches(void) | |||
948 | if (!ocfs2_inode_cachep) | 957 | if (!ocfs2_inode_cachep) |
949 | return -ENOMEM; | 958 | return -ENOMEM; |
950 | 959 | ||
951 | ocfs2_lock_cache = kmem_cache_create("ocfs2_lock", | ||
952 | sizeof(struct ocfs2_journal_lock), | ||
953 | 0, | ||
954 | SLAB_HWCACHE_ALIGN, | ||
955 | NULL, NULL); | ||
956 | if (!ocfs2_lock_cache) | ||
957 | return -ENOMEM; | ||
958 | |||
959 | return 0; | 960 | return 0; |
960 | } | 961 | } |
961 | 962 | ||
@@ -963,11 +964,8 @@ static void ocfs2_free_mem_caches(void) | |||
963 | { | 964 | { |
964 | if (ocfs2_inode_cachep) | 965 | if (ocfs2_inode_cachep) |
965 | kmem_cache_destroy(ocfs2_inode_cachep); | 966 | kmem_cache_destroy(ocfs2_inode_cachep); |
966 | if (ocfs2_lock_cache) | ||
967 | kmem_cache_destroy(ocfs2_lock_cache); | ||
968 | 967 | ||
969 | ocfs2_inode_cachep = NULL; | 968 | ocfs2_inode_cachep = NULL; |
970 | ocfs2_lock_cache = NULL; | ||
971 | } | 969 | } |
972 | 970 | ||
973 | static int ocfs2_get_sector(struct super_block *sb, | 971 | static int ocfs2_get_sector(struct super_block *sb, |
@@ -1280,6 +1278,8 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1280 | init_waitqueue_head(&osb->checkpoint_event); | 1278 | init_waitqueue_head(&osb->checkpoint_event); |
1281 | atomic_set(&osb->needs_checkpoint, 0); | 1279 | atomic_set(&osb->needs_checkpoint, 0); |
1282 | 1280 | ||
1281 | osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM; | ||
1282 | |||
1283 | osb->node_num = O2NM_INVALID_NODE_NUM; | 1283 | osb->node_num = O2NM_INVALID_NODE_NUM; |
1284 | osb->slot_num = OCFS2_INVALID_SLOT; | 1284 | osb->slot_num = OCFS2_INVALID_SLOT; |
1285 | 1285 | ||
@@ -1365,7 +1365,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
1365 | spin_lock_init(&journal->j_lock); | 1365 | spin_lock_init(&journal->j_lock); |
1366 | journal->j_trans_id = (unsigned long) 1; | 1366 | journal->j_trans_id = (unsigned long) 1; |
1367 | INIT_LIST_HEAD(&journal->j_la_cleanups); | 1367 | INIT_LIST_HEAD(&journal->j_la_cleanups); |
1368 | INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery, osb); | 1368 | INIT_WORK(&journal->j_recovery_work, ocfs2_complete_recovery); |
1369 | journal->j_state = OCFS2_JOURNAL_FREE; | 1369 | journal->j_state = OCFS2_JOURNAL_FREE; |
1370 | 1370 | ||
1371 | /* get some pseudo constants for clustersize bits */ | 1371 | /* get some pseudo constants for clustersize bits */ |
@@ -1674,7 +1674,7 @@ void __ocfs2_error(struct super_block *sb, | |||
1674 | va_list args; | 1674 | va_list args; |
1675 | 1675 | ||
1676 | va_start(args, fmt); | 1676 | va_start(args, fmt); |
1677 | vsprintf(error_buf, fmt, args); | 1677 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
1678 | va_end(args); | 1678 | va_end(args); |
1679 | 1679 | ||
1680 | /* Not using mlog here because we want to show the actual | 1680 | /* Not using mlog here because we want to show the actual |
@@ -1695,7 +1695,7 @@ void __ocfs2_abort(struct super_block* sb, | |||
1695 | va_list args; | 1695 | va_list args; |
1696 | 1696 | ||
1697 | va_start(args, fmt); | 1697 | va_start(args, fmt); |
1698 | vsprintf(error_buf, fmt, args); | 1698 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
1699 | va_end(args); | 1699 | va_end(args); |
1700 | 1700 | ||
1701 | printk(KERN_CRIT "OCFS2: abort (device %s): %s: %s\n", | 1701 | printk(KERN_CRIT "OCFS2: abort (device %s): %s: %s\n", |
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c index c0f68aa6c175..957d6878b03e 100644 --- a/fs/ocfs2/symlink.c +++ b/fs/ocfs2/symlink.c | |||
@@ -126,6 +126,10 @@ static int ocfs2_readlink(struct dentry *dentry, | |||
126 | goto out; | 126 | goto out; |
127 | } | 127 | } |
128 | 128 | ||
129 | /* | ||
130 | * Without vfsmount we can't update atime now, | ||
131 | * but we will update atime here ultimately. | ||
132 | */ | ||
129 | ret = vfs_readlink(dentry, buffer, buflen, link); | 133 | ret = vfs_readlink(dentry, buffer, buflen, link); |
130 | 134 | ||
131 | brelse(bh); | 135 | brelse(bh); |
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c index 9707ed7a3206..39814b900fc0 100644 --- a/fs/ocfs2/uptodate.c +++ b/fs/ocfs2/uptodate.c | |||
@@ -69,7 +69,7 @@ struct ocfs2_meta_cache_item { | |||
69 | sector_t c_block; | 69 | sector_t c_block; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static kmem_cache_t *ocfs2_uptodate_cachep = NULL; | 72 | static struct kmem_cache *ocfs2_uptodate_cachep = NULL; |
73 | 73 | ||
74 | void ocfs2_metadata_cache_init(struct inode *inode) | 74 | void ocfs2_metadata_cache_init(struct inode *inode) |
75 | { | 75 | { |
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index 592a6402e851..26f44e0074ec 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c | |||
@@ -330,13 +330,13 @@ out: | |||
330 | return 0; | 330 | return 0; |
331 | } | 331 | } |
332 | 332 | ||
333 | static kmem_cache_t *op_inode_cachep; | 333 | static struct kmem_cache *op_inode_cachep; |
334 | 334 | ||
335 | static struct inode *openprom_alloc_inode(struct super_block *sb) | 335 | static struct inode *openprom_alloc_inode(struct super_block *sb) |
336 | { | 336 | { |
337 | struct op_inode_info *oi; | 337 | struct op_inode_info *oi; |
338 | 338 | ||
339 | oi = kmem_cache_alloc(op_inode_cachep, SLAB_KERNEL); | 339 | oi = kmem_cache_alloc(op_inode_cachep, GFP_KERNEL); |
340 | if (!oi) | 340 | if (!oi) |
341 | return NULL; | 341 | return NULL; |
342 | 342 | ||
@@ -415,7 +415,7 @@ static struct file_system_type openprom_fs_type = { | |||
415 | .kill_sb = kill_anon_super, | 415 | .kill_sb = kill_anon_super, |
416 | }; | 416 | }; |
417 | 417 | ||
418 | static void op_inode_init_once(void *data, kmem_cache_t * cachep, unsigned long flags) | 418 | static void op_inode_init_once(void *data, struct kmem_cache * cachep, unsigned long flags) |
419 | { | 419 | { |
420 | struct op_inode_info *oi = (struct op_inode_info *) data; | 420 | struct op_inode_info *oi = (struct op_inode_info *) data; |
421 | 421 | ||
diff --git a/fs/partitions/amiga.c b/fs/partitions/amiga.c index 3068528890a6..9917a8c360f2 100644 --- a/fs/partitions/amiga.c +++ b/fs/partitions/amiga.c | |||
@@ -43,6 +43,7 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
43 | if (warn_no_part) | 43 | if (warn_no_part) |
44 | printk("Dev %s: unable to read RDB block %d\n", | 44 | printk("Dev %s: unable to read RDB block %d\n", |
45 | bdevname(bdev, b), blk); | 45 | bdevname(bdev, b), blk); |
46 | res = -1; | ||
46 | goto rdb_done; | 47 | goto rdb_done; |
47 | } | 48 | } |
48 | if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) | 49 | if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) |
@@ -79,6 +80,7 @@ amiga_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
79 | if (warn_no_part) | 80 | if (warn_no_part) |
80 | printk("Dev %s: unable to read partition block %d\n", | 81 | printk("Dev %s: unable to read partition block %d\n", |
81 | bdevname(bdev, b), blk); | 82 | bdevname(bdev, b), blk); |
83 | res = -1; | ||
82 | goto rdb_done; | 84 | goto rdb_done; |
83 | } | 85 | } |
84 | pb = (struct PartitionBlock *)data; | 86 | pb = (struct PartitionBlock *)data; |
diff --git a/fs/partitions/atari.c b/fs/partitions/atari.c index 192a6adfdefd..1f3572d5b755 100644 --- a/fs/partitions/atari.c +++ b/fs/partitions/atari.c | |||
@@ -88,7 +88,7 @@ int atari_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
88 | if (!xrs) { | 88 | if (!xrs) { |
89 | printk (" block %ld read failed\n", partsect); | 89 | printk (" block %ld read failed\n", partsect); |
90 | put_dev_sector(sect); | 90 | put_dev_sector(sect); |
91 | return 0; | 91 | return -1; |
92 | } | 92 | } |
93 | 93 | ||
94 | /* ++roman: sanity check: bit 0 of flg field must be set */ | 94 | /* ++roman: sanity check: bit 0 of flg field must be set */ |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 6fb4b6150d77..1901137f4eca 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -153,7 +153,7 @@ static struct parsed_partitions * | |||
153 | check_partition(struct gendisk *hd, struct block_device *bdev) | 153 | check_partition(struct gendisk *hd, struct block_device *bdev) |
154 | { | 154 | { |
155 | struct parsed_partitions *state; | 155 | struct parsed_partitions *state; |
156 | int i, res; | 156 | int i, res, err; |
157 | 157 | ||
158 | state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); | 158 | state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL); |
159 | if (!state) | 159 | if (!state) |
@@ -165,19 +165,30 @@ check_partition(struct gendisk *hd, struct block_device *bdev) | |||
165 | sprintf(state->name, "p"); | 165 | sprintf(state->name, "p"); |
166 | 166 | ||
167 | state->limit = hd->minors; | 167 | state->limit = hd->minors; |
168 | i = res = 0; | 168 | i = res = err = 0; |
169 | while (!res && check_part[i]) { | 169 | while (!res && check_part[i]) { |
170 | memset(&state->parts, 0, sizeof(state->parts)); | 170 | memset(&state->parts, 0, sizeof(state->parts)); |
171 | res = check_part[i++](state, bdev); | 171 | res = check_part[i++](state, bdev); |
172 | if (res < 0) { | ||
173 | /* We have hit an I/O error which we don't report now. | ||
174 | * But record it, and let the others do their job. | ||
175 | */ | ||
176 | err = res; | ||
177 | res = 0; | ||
178 | } | ||
179 | |||
172 | } | 180 | } |
173 | if (res > 0) | 181 | if (res > 0) |
174 | return state; | 182 | return state; |
183 | if (!err) | ||
184 | /* The partition is unrecognized. So report I/O errors if there were any */ | ||
185 | res = err; | ||
175 | if (!res) | 186 | if (!res) |
176 | printk(" unknown partition table\n"); | 187 | printk(" unknown partition table\n"); |
177 | else if (warn_no_part) | 188 | else if (warn_no_part) |
178 | printk(" unable to read partition table\n"); | 189 | printk(" unable to read partition table\n"); |
179 | kfree(state); | 190 | kfree(state); |
180 | return NULL; | 191 | return ERR_PTR(res); |
181 | } | 192 | } |
182 | 193 | ||
183 | /* | 194 | /* |
@@ -494,6 +505,8 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) | |||
494 | disk->fops->revalidate_disk(disk); | 505 | disk->fops->revalidate_disk(disk); |
495 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) | 506 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) |
496 | return 0; | 507 | return 0; |
508 | if (IS_ERR(state)) /* I/O error reading the partition table */ | ||
509 | return PTR_ERR(state); | ||
497 | for (p = 1; p < state->limit; p++) { | 510 | for (p = 1; p < state->limit; p++) { |
498 | sector_t size = state->parts[p].size; | 511 | sector_t size = state->parts[p].size; |
499 | sector_t from = state->parts[p].from; | 512 | sector_t from = state->parts[p].from; |
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index d352a7381fed..9f7ad4244f63 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c | |||
@@ -43,7 +43,7 @@ cchhb2blk (struct vtoc_cchhb *ptr, struct hd_geometry *geo) { | |||
43 | int | 43 | int |
44 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | 44 | ibm_partition(struct parsed_partitions *state, struct block_device *bdev) |
45 | { | 45 | { |
46 | int blocksize, offset, size; | 46 | int blocksize, offset, size,res; |
47 | loff_t i_size; | 47 | loff_t i_size; |
48 | dasd_information_t *info; | 48 | dasd_information_t *info; |
49 | struct hd_geometry *geo; | 49 | struct hd_geometry *geo; |
@@ -56,15 +56,16 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
56 | unsigned char *data; | 56 | unsigned char *data; |
57 | Sector sect; | 57 | Sector sect; |
58 | 58 | ||
59 | res = 0; | ||
59 | blocksize = bdev_hardsect_size(bdev); | 60 | blocksize = bdev_hardsect_size(bdev); |
60 | if (blocksize <= 0) | 61 | if (blocksize <= 0) |
61 | return 0; | 62 | goto out_exit; |
62 | i_size = i_size_read(bdev->bd_inode); | 63 | i_size = i_size_read(bdev->bd_inode); |
63 | if (i_size == 0) | 64 | if (i_size == 0) |
64 | return 0; | 65 | goto out_exit; |
65 | 66 | ||
66 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) | 67 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) |
67 | goto out_noinfo; | 68 | goto out_exit; |
68 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) | 69 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) |
69 | goto out_nogeo; | 70 | goto out_nogeo; |
70 | if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) | 71 | if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) |
@@ -72,7 +73,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
72 | 73 | ||
73 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || | 74 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || |
74 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) | 75 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) |
75 | goto out_noioctl; | 76 | goto out_freeall; |
76 | 77 | ||
77 | /* | 78 | /* |
78 | * Get volume label, extract name and type. | 79 | * Get volume label, extract name and type. |
@@ -92,6 +93,8 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
92 | EBCASC(type, 4); | 93 | EBCASC(type, 4); |
93 | EBCASC(name, 6); | 94 | EBCASC(name, 6); |
94 | 95 | ||
96 | res = 1; | ||
97 | |||
95 | /* | 98 | /* |
96 | * Three different types: CMS1, VOL1 and LNX1/unlabeled | 99 | * Three different types: CMS1, VOL1 and LNX1/unlabeled |
97 | */ | 100 | */ |
@@ -156,6 +159,9 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
156 | counter++; | 159 | counter++; |
157 | blk++; | 160 | blk++; |
158 | } | 161 | } |
162 | if (!data) | ||
163 | /* Are we not supposed to report this ? */ | ||
164 | goto out_readerr; | ||
159 | } else { | 165 | } else { |
160 | /* | 166 | /* |
161 | * Old style LNX1 or unlabeled disk | 167 | * Old style LNX1 or unlabeled disk |
@@ -171,18 +177,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
171 | } | 177 | } |
172 | 178 | ||
173 | printk("\n"); | 179 | printk("\n"); |
174 | kfree(label); | 180 | goto out_freeall; |
175 | kfree(geo); | 181 | |
176 | kfree(info); | ||
177 | return 1; | ||
178 | 182 | ||
179 | out_readerr: | 183 | out_readerr: |
180 | out_noioctl: | 184 | res = -1; |
185 | out_freeall: | ||
181 | kfree(label); | 186 | kfree(label); |
182 | out_nolab: | 187 | out_nolab: |
183 | kfree(geo); | 188 | kfree(geo); |
184 | out_nogeo: | 189 | out_nogeo: |
185 | kfree(info); | 190 | kfree(info); |
186 | out_noinfo: | 191 | out_exit: |
187 | return 0; | 192 | return res; |
188 | } | 193 | } |
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c index c0871002d00d..d4a0fad3563b 100644 --- a/fs/partitions/mac.c +++ b/fs/partitions/mac.c | |||
@@ -74,6 +74,8 @@ int mac_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
74 | be32_to_cpu(part->start_block) * (secsize/512), | 74 | be32_to_cpu(part->start_block) * (secsize/512), |
75 | be32_to_cpu(part->block_count) * (secsize/512)); | 75 | be32_to_cpu(part->block_count) * (secsize/512)); |
76 | 76 | ||
77 | if (!strnicmp(part->type, "Linux_RAID", 10)) | ||
78 | state->parts[slot].flags = 1; | ||
77 | #ifdef CONFIG_PPC_PMAC | 79 | #ifdef CONFIG_PPC_PMAC |
78 | /* | 80 | /* |
79 | * If this is the first bootable partition, tell the | 81 | * If this is the first bootable partition, tell the |
@@ -830,7 +830,14 @@ void free_pipe_info(struct inode *inode) | |||
830 | static struct vfsmount *pipe_mnt __read_mostly; | 830 | static struct vfsmount *pipe_mnt __read_mostly; |
831 | static int pipefs_delete_dentry(struct dentry *dentry) | 831 | static int pipefs_delete_dentry(struct dentry *dentry) |
832 | { | 832 | { |
833 | return 1; | 833 | /* |
834 | * At creation time, we pretended this dentry was hashed | ||
835 | * (by clearing DCACHE_UNHASHED bit in d_flags) | ||
836 | * At delete time, we restore the truth : not hashed. | ||
837 | * (so that dput() can proceed correctly) | ||
838 | */ | ||
839 | dentry->d_flags |= DCACHE_UNHASHED; | ||
840 | return 0; | ||
834 | } | 841 | } |
835 | 842 | ||
836 | static struct dentry_operations pipefs_dentry_operations = { | 843 | static struct dentry_operations pipefs_dentry_operations = { |
@@ -891,17 +898,22 @@ struct file *create_write_pipe(void) | |||
891 | if (!inode) | 898 | if (!inode) |
892 | goto err_file; | 899 | goto err_file; |
893 | 900 | ||
894 | sprintf(name, "[%lu]", inode->i_ino); | 901 | this.len = sprintf(name, "[%lu]", inode->i_ino); |
895 | this.name = name; | 902 | this.name = name; |
896 | this.len = strlen(name); | 903 | this.hash = 0; |
897 | this.hash = inode->i_ino; /* will go */ | ||
898 | err = -ENOMEM; | 904 | err = -ENOMEM; |
899 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); | 905 | dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &this); |
900 | if (!dentry) | 906 | if (!dentry) |
901 | goto err_inode; | 907 | goto err_inode; |
902 | 908 | ||
903 | dentry->d_op = &pipefs_dentry_operations; | 909 | dentry->d_op = &pipefs_dentry_operations; |
904 | d_add(dentry, inode); | 910 | /* |
911 | * We dont want to publish this dentry into global dentry hash table. | ||
912 | * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED | ||
913 | * This permits a working /proc/$pid/fd/XXX on pipes | ||
914 | */ | ||
915 | dentry->d_flags &= ~DCACHE_UNHASHED; | ||
916 | d_instantiate(dentry, inode); | ||
905 | f->f_vfsmnt = mntget(pipe_mnt); | 917 | f->f_vfsmnt = mntget(pipe_mnt); |
906 | f->f_dentry = dentry; | 918 | f->f_dentry = dentry; |
907 | f->f_mapping = inode->i_mapping; | 919 | f->f_mapping = inode->i_mapping; |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index 7431d7ba2d09..f6c776272572 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -8,8 +8,9 @@ proc-y := nommu.o task_nommu.o | |||
8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o | 8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o |
9 | 9 | ||
10 | proc-y += inode.o root.o base.o generic.o array.o \ | 10 | proc-y += inode.o root.o base.o generic.o array.o \ |
11 | kmsg.o proc_tty.o proc_misc.o | 11 | proc_tty.o proc_misc.o |
12 | 12 | ||
13 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 13 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
14 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o | 14 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o |
15 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | 15 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o |
16 | proc-$(CONFIG_PRINTK) += kmsg.o | ||
diff --git a/fs/proc/base.c b/fs/proc/base.c index 8df27401d292..b859fc749c07 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -442,7 +442,8 @@ static int mountstats_open(struct inode *inode, struct file *file) | |||
442 | 442 | ||
443 | if (task) { | 443 | if (task) { |
444 | task_lock(task); | 444 | task_lock(task); |
445 | namespace = task->nsproxy->namespace; | 445 | if (task->nsproxy) |
446 | namespace = task->nsproxy->namespace; | ||
446 | if (namespace) | 447 | if (namespace) |
447 | get_namespace(namespace); | 448 | get_namespace(namespace); |
448 | task_unlock(task); | 449 | task_unlock(task); |
@@ -682,8 +683,6 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | |||
682 | char buffer[PROC_NUMBUF], *end; | 683 | char buffer[PROC_NUMBUF], *end; |
683 | int oom_adjust; | 684 | int oom_adjust; |
684 | 685 | ||
685 | if (!capable(CAP_SYS_RESOURCE)) | ||
686 | return -EPERM; | ||
687 | memset(buffer, 0, sizeof(buffer)); | 686 | memset(buffer, 0, sizeof(buffer)); |
688 | if (count > sizeof(buffer) - 1) | 687 | if (count > sizeof(buffer) - 1) |
689 | count = sizeof(buffer) - 1; | 688 | count = sizeof(buffer) - 1; |
@@ -698,6 +697,10 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, | |||
698 | task = get_proc_task(file->f_dentry->d_inode); | 697 | task = get_proc_task(file->f_dentry->d_inode); |
699 | if (!task) | 698 | if (!task) |
700 | return -ESRCH; | 699 | return -ESRCH; |
700 | if (oom_adjust < task->oomkilladj && !capable(CAP_SYS_RESOURCE)) { | ||
701 | put_task_struct(task); | ||
702 | return -EACCES; | ||
703 | } | ||
701 | task->oomkilladj = oom_adjust; | 704 | task->oomkilladj = oom_adjust; |
702 | put_task_struct(task); | 705 | put_task_struct(task); |
703 | if (end - buffer == 0) | 706 | if (end - buffer == 0) |
@@ -1882,8 +1885,9 @@ out: | |||
1882 | return; | 1885 | return; |
1883 | } | 1886 | } |
1884 | 1887 | ||
1885 | struct dentry *proc_pid_instantiate(struct inode *dir, | 1888 | static struct dentry *proc_pid_instantiate(struct inode *dir, |
1886 | struct dentry * dentry, struct task_struct *task, void *ptr) | 1889 | struct dentry * dentry, |
1890 | struct task_struct *task, void *ptr) | ||
1887 | { | 1891 | { |
1888 | struct dentry *error = ERR_PTR(-ENOENT); | 1892 | struct dentry *error = ERR_PTR(-ENOENT); |
1889 | struct inode *inode; | 1893 | struct inode *inode; |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 49dfb2ab783e..e26945ba685b 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -81,14 +81,14 @@ static void proc_read_inode(struct inode * inode) | |||
81 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 81 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
82 | } | 82 | } |
83 | 83 | ||
84 | static kmem_cache_t * proc_inode_cachep; | 84 | static struct kmem_cache * proc_inode_cachep; |
85 | 85 | ||
86 | static struct inode *proc_alloc_inode(struct super_block *sb) | 86 | static struct inode *proc_alloc_inode(struct super_block *sb) |
87 | { | 87 | { |
88 | struct proc_inode *ei; | 88 | struct proc_inode *ei; |
89 | struct inode *inode; | 89 | struct inode *inode; |
90 | 90 | ||
91 | ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, SLAB_KERNEL); | 91 | ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, GFP_KERNEL); |
92 | if (!ei) | 92 | if (!ei) |
93 | return NULL; | 93 | return NULL; |
94 | ei->pid = NULL; | 94 | ei->pid = NULL; |
@@ -105,7 +105,7 @@ static void proc_destroy_inode(struct inode *inode) | |||
105 | kmem_cache_free(proc_inode_cachep, PROC_I(inode)); | 105 | kmem_cache_free(proc_inode_cachep, PROC_I(inode)); |
106 | } | 106 | } |
107 | 107 | ||
108 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 108 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
109 | { | 109 | { |
110 | struct proc_inode *ei = (struct proc_inode *) foo; | 110 | struct proc_inode *ei = (struct proc_inode *) foo; |
111 | 111 | ||
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 1294eda4acae..1be73082edd3 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
24 | 24 | ||
25 | #define CORE_STR "CORE" | ||
25 | 26 | ||
26 | static int open_kcore(struct inode * inode, struct file * filp) | 27 | static int open_kcore(struct inode * inode, struct file * filp) |
27 | { | 28 | { |
@@ -82,10 +83,11 @@ static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) | |||
82 | } | 83 | } |
83 | *elf_buflen = sizeof(struct elfhdr) + | 84 | *elf_buflen = sizeof(struct elfhdr) + |
84 | (*nphdr + 2)*sizeof(struct elf_phdr) + | 85 | (*nphdr + 2)*sizeof(struct elf_phdr) + |
85 | 3 * (sizeof(struct elf_note) + 4) + | 86 | 3 * ((sizeof(struct elf_note)) + |
86 | sizeof(struct elf_prstatus) + | 87 | roundup(sizeof(CORE_STR), 4)) + |
87 | sizeof(struct elf_prpsinfo) + | 88 | roundup(sizeof(struct elf_prstatus), 4) + |
88 | sizeof(struct task_struct); | 89 | roundup(sizeof(struct elf_prpsinfo), 4) + |
90 | roundup(sizeof(struct task_struct), 4); | ||
89 | *elf_buflen = PAGE_ALIGN(*elf_buflen); | 91 | *elf_buflen = PAGE_ALIGN(*elf_buflen); |
90 | return size + *elf_buflen; | 92 | return size + *elf_buflen; |
91 | } | 93 | } |
@@ -210,7 +212,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) | |||
210 | nhdr->p_offset = offset; | 212 | nhdr->p_offset = offset; |
211 | 213 | ||
212 | /* set up the process status */ | 214 | /* set up the process status */ |
213 | notes[0].name = "CORE"; | 215 | notes[0].name = CORE_STR; |
214 | notes[0].type = NT_PRSTATUS; | 216 | notes[0].type = NT_PRSTATUS; |
215 | notes[0].datasz = sizeof(struct elf_prstatus); | 217 | notes[0].datasz = sizeof(struct elf_prstatus); |
216 | notes[0].data = &prstatus; | 218 | notes[0].data = &prstatus; |
@@ -221,7 +223,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) | |||
221 | bufp = storenote(¬es[0], bufp); | 223 | bufp = storenote(¬es[0], bufp); |
222 | 224 | ||
223 | /* set up the process info */ | 225 | /* set up the process info */ |
224 | notes[1].name = "CORE"; | 226 | notes[1].name = CORE_STR; |
225 | notes[1].type = NT_PRPSINFO; | 227 | notes[1].type = NT_PRPSINFO; |
226 | notes[1].datasz = sizeof(struct elf_prpsinfo); | 228 | notes[1].datasz = sizeof(struct elf_prpsinfo); |
227 | notes[1].data = &prpsinfo; | 229 | notes[1].data = &prpsinfo; |
@@ -238,7 +240,7 @@ static void elf_kcore_store_hdr(char *bufp, int nphdr, int dataoff) | |||
238 | bufp = storenote(¬es[1], bufp); | 240 | bufp = storenote(¬es[1], bufp); |
239 | 241 | ||
240 | /* set up the task structure */ | 242 | /* set up the task structure */ |
241 | notes[2].name = "CORE"; | 243 | notes[2].name = CORE_STR; |
242 | notes[2].type = NT_TASKSTRUCT; | 244 | notes[2].type = NT_TASKSTRUCT; |
243 | notes[2].datasz = sizeof(struct task_struct); | 245 | notes[2].datasz = sizeof(struct task_struct); |
244 | notes[2].data = current; | 246 | notes[2].data = current; |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 93c43b676e59..51815cece6f3 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -696,9 +696,11 @@ void __init proc_misc_init(void) | |||
696 | proc_symlink("mounts", NULL, "self/mounts"); | 696 | proc_symlink("mounts", NULL, "self/mounts"); |
697 | 697 | ||
698 | /* And now for trickier ones */ | 698 | /* And now for trickier ones */ |
699 | #ifdef CONFIG_PRINTK | ||
699 | entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); | 700 | entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); |
700 | if (entry) | 701 | if (entry) |
701 | entry->proc_fops = &proc_kmsg_operations; | 702 | entry->proc_fops = &proc_kmsg_operations; |
703 | #endif | ||
702 | create_seq_entry("devices", 0, &proc_devinfo_operations); | 704 | create_seq_entry("devices", 0, &proc_devinfo_operations); |
703 | create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); | 705 | create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); |
704 | #ifdef CONFIG_BLOCK | 706 | #ifdef CONFIG_BLOCK |
diff --git a/fs/proc/root.c b/fs/proc/root.c index ffe66c38488b..64d242b6dcfa 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/proc_fs.h> | 13 | #include <linux/proc_fs.h> |
14 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/sched.h> | ||
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
17 | #include <linux/bitops.h> | 18 | #include <linux/bitops.h> |
18 | #include <linux/smp_lock.h> | 19 | #include <linux/smp_lock.h> |
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 5a41db2a218d..c047dc654d5c 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c | |||
@@ -515,12 +515,12 @@ static void qnx4_read_inode(struct inode *inode) | |||
515 | brelse(bh); | 515 | brelse(bh); |
516 | } | 516 | } |
517 | 517 | ||
518 | static kmem_cache_t *qnx4_inode_cachep; | 518 | static struct kmem_cache *qnx4_inode_cachep; |
519 | 519 | ||
520 | static struct inode *qnx4_alloc_inode(struct super_block *sb) | 520 | static struct inode *qnx4_alloc_inode(struct super_block *sb) |
521 | { | 521 | { |
522 | struct qnx4_inode_info *ei; | 522 | struct qnx4_inode_info *ei; |
523 | ei = kmem_cache_alloc(qnx4_inode_cachep, SLAB_KERNEL); | 523 | ei = kmem_cache_alloc(qnx4_inode_cachep, GFP_KERNEL); |
524 | if (!ei) | 524 | if (!ei) |
525 | return NULL; | 525 | return NULL; |
526 | return &ei->vfs_inode; | 526 | return &ei->vfs_inode; |
@@ -531,7 +531,7 @@ static void qnx4_destroy_inode(struct inode *inode) | |||
531 | kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); | 531 | kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); |
532 | } | 532 | } |
533 | 533 | ||
534 | static void init_once(void *foo, kmem_cache_t * cachep, | 534 | static void init_once(void *foo, struct kmem_cache * cachep, |
535 | unsigned long flags) | 535 | unsigned long flags) |
536 | { | 536 | { |
537 | struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; | 537 | struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo; |
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index b67ce9354048..373d862c3f87 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c | |||
@@ -74,7 +74,8 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) | |||
74 | igrab(inode); | 74 | igrab(inode); |
75 | reiserfs_warning(inode->i_sb, | 75 | reiserfs_warning(inode->i_sb, |
76 | "pinning inode %lu because the " | 76 | "pinning inode %lu because the " |
77 | "preallocation can't be freed"); | 77 | "preallocation can't be freed", |
78 | inode->i_ino); | ||
78 | goto out; | 79 | goto out; |
79 | } | 80 | } |
80 | } | 81 | } |
@@ -316,12 +317,11 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl | |||
316 | /* area filled with zeroes, to supply as list of zero blocknumbers | 317 | /* area filled with zeroes, to supply as list of zero blocknumbers |
317 | We allocate it outside of loop just in case loop would spin for | 318 | We allocate it outside of loop just in case loop would spin for |
318 | several iterations. */ | 319 | several iterations. */ |
319 | char *zeros = kmalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway. | 320 | char *zeros = kzalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway. |
320 | if (!zeros) { | 321 | if (!zeros) { |
321 | res = -ENOMEM; | 322 | res = -ENOMEM; |
322 | goto error_exit_free_blocks; | 323 | goto error_exit_free_blocks; |
323 | } | 324 | } |
324 | memset(zeros, 0, to_paste * UNFM_P_SIZE); | ||
325 | do { | 325 | do { |
326 | to_paste = | 326 | to_paste = |
327 | min_t(__u64, hole_size, | 327 | min_t(__u64, hole_size, |
@@ -406,6 +406,8 @@ static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handl | |||
406 | we restart it. This will also free the path. */ | 406 | we restart it. This will also free the path. */ |
407 | if (journal_transaction_should_end | 407 | if (journal_transaction_should_end |
408 | (th, th->t_blocks_allocated)) { | 408 | (th, th->t_blocks_allocated)) { |
409 | inode->i_size = cpu_key_k_offset(&key) + | ||
410 | (to_paste << inode->i_blkbits); | ||
409 | res = | 411 | res = |
410 | restart_transaction(th, inode, | 412 | restart_transaction(th, inode, |
411 | &path); | 413 | &path); |
@@ -1044,6 +1046,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1044 | char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); | 1046 | char *kaddr = kmap_atomic(prepared_pages[0], KM_USER0); |
1045 | memset(kaddr, 0, from); | 1047 | memset(kaddr, 0, from); |
1046 | kunmap_atomic(kaddr, KM_USER0); | 1048 | kunmap_atomic(kaddr, KM_USER0); |
1049 | flush_dcache_page(prepared_pages[0]); | ||
1047 | } | 1050 | } |
1048 | if (to != PAGE_CACHE_SIZE) { /* Last page needs to be partially zeroed */ | 1051 | if (to != PAGE_CACHE_SIZE) { /* Last page needs to be partially zeroed */ |
1049 | char *kaddr = | 1052 | char *kaddr = |
@@ -1051,6 +1054,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1051 | KM_USER0); | 1054 | KM_USER0); |
1052 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); | 1055 | memset(kaddr + to, 0, PAGE_CACHE_SIZE - to); |
1053 | kunmap_atomic(kaddr, KM_USER0); | 1056 | kunmap_atomic(kaddr, KM_USER0); |
1057 | flush_dcache_page(prepared_pages[num_pages - 1]); | ||
1054 | } | 1058 | } |
1055 | 1059 | ||
1056 | /* Since all blocks are new - use already calculated value */ | 1060 | /* Since all blocks are new - use already calculated value */ |
@@ -1184,6 +1188,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1184 | memset(kaddr + block_start, 0, | 1188 | memset(kaddr + block_start, 0, |
1185 | from - block_start); | 1189 | from - block_start); |
1186 | kunmap_atomic(kaddr, KM_USER0); | 1190 | kunmap_atomic(kaddr, KM_USER0); |
1191 | flush_dcache_page(prepared_pages[0]); | ||
1187 | set_buffer_uptodate(bh); | 1192 | set_buffer_uptodate(bh); |
1188 | } | 1193 | } |
1189 | } | 1194 | } |
@@ -1221,6 +1226,7 @@ static int reiserfs_prepare_file_region_for_write(struct inode *inode | |||
1221 | KM_USER0); | 1226 | KM_USER0); |
1222 | memset(kaddr + to, 0, block_end - to); | 1227 | memset(kaddr + to, 0, block_end - to); |
1223 | kunmap_atomic(kaddr, KM_USER0); | 1228 | kunmap_atomic(kaddr, KM_USER0); |
1229 | flush_dcache_page(prepared_pages[num_pages - 1]); | ||
1224 | set_buffer_uptodate(bh); | 1230 | set_buffer_uptodate(bh); |
1225 | } | 1231 | } |
1226 | } | 1232 | } |
@@ -1306,56 +1312,8 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t | |||
1306 | count = MAX_NON_LFS - (unsigned long)*ppos; | 1312 | count = MAX_NON_LFS - (unsigned long)*ppos; |
1307 | } | 1313 | } |
1308 | 1314 | ||
1309 | if (file->f_flags & O_DIRECT) { // Direct IO needs treatment | 1315 | if (file->f_flags & O_DIRECT) |
1310 | ssize_t result, after_file_end = 0; | 1316 | return do_sync_write(file, buf, count, ppos); |
1311 | if ((*ppos + count >= inode->i_size) | ||
1312 | || (file->f_flags & O_APPEND)) { | ||
1313 | /* If we are appending a file, we need to put this savelink in here. | ||
1314 | If we will crash while doing direct io, finish_unfinished will | ||
1315 | cut the garbage from the file end. */ | ||
1316 | reiserfs_write_lock(inode->i_sb); | ||
1317 | err = | ||
1318 | journal_begin(&th, inode->i_sb, | ||
1319 | JOURNAL_PER_BALANCE_CNT); | ||
1320 | if (err) { | ||
1321 | reiserfs_write_unlock(inode->i_sb); | ||
1322 | return err; | ||
1323 | } | ||
1324 | reiserfs_update_inode_transaction(inode); | ||
1325 | add_save_link(&th, inode, 1 /* Truncate */ ); | ||
1326 | after_file_end = 1; | ||
1327 | err = | ||
1328 | journal_end(&th, inode->i_sb, | ||
1329 | JOURNAL_PER_BALANCE_CNT); | ||
1330 | reiserfs_write_unlock(inode->i_sb); | ||
1331 | if (err) | ||
1332 | return err; | ||
1333 | } | ||
1334 | result = do_sync_write(file, buf, count, ppos); | ||
1335 | |||
1336 | if (after_file_end) { /* Now update i_size and remove the savelink */ | ||
1337 | struct reiserfs_transaction_handle th; | ||
1338 | reiserfs_write_lock(inode->i_sb); | ||
1339 | err = journal_begin(&th, inode->i_sb, 1); | ||
1340 | if (err) { | ||
1341 | reiserfs_write_unlock(inode->i_sb); | ||
1342 | return err; | ||
1343 | } | ||
1344 | reiserfs_update_inode_transaction(inode); | ||
1345 | mark_inode_dirty(inode); | ||
1346 | err = journal_end(&th, inode->i_sb, 1); | ||
1347 | if (err) { | ||
1348 | reiserfs_write_unlock(inode->i_sb); | ||
1349 | return err; | ||
1350 | } | ||
1351 | err = remove_save_link(inode, 1 /* truncate */ ); | ||
1352 | reiserfs_write_unlock(inode->i_sb); | ||
1353 | if (err) | ||
1354 | return err; | ||
1355 | } | ||
1356 | |||
1357 | return result; | ||
1358 | } | ||
1359 | 1317 | ||
1360 | if (unlikely((ssize_t) count < 0)) | 1318 | if (unlikely((ssize_t) count < 0)) |
1361 | return -EINVAL; | 1319 | return -EINVAL; |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 9c69bcacad22..254239e6f9e3 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -216,11 +216,12 @@ static int file_capable(struct inode *inode, long block) | |||
216 | BUG_ON(!th->t_trans_id); | 216 | BUG_ON(!th->t_trans_id); |
217 | BUG_ON(!th->t_refcount); | 217 | BUG_ON(!th->t_refcount); |
218 | 218 | ||
219 | pathrelse(path); | ||
220 | |||
219 | /* we cannot restart while nested */ | 221 | /* we cannot restart while nested */ |
220 | if (th->t_refcount > 1) { | 222 | if (th->t_refcount > 1) { |
221 | return 0; | 223 | return 0; |
222 | } | 224 | } |
223 | pathrelse(path); | ||
224 | reiserfs_update_sd(th, inode); | 225 | reiserfs_update_sd(th, inode); |
225 | err = journal_end(th, s, len); | 226 | err = journal_end(th, s, len); |
226 | if (!err) { | 227 | if (!err) { |
@@ -928,15 +929,12 @@ int reiserfs_get_block(struct inode *inode, sector_t block, | |||
928 | if (blocks_needed == 1) { | 929 | if (blocks_needed == 1) { |
929 | un = &unf_single; | 930 | un = &unf_single; |
930 | } else { | 931 | } else { |
931 | un = kmalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC); // We need to avoid scheduling. | 932 | un = kzalloc(min(blocks_needed, max_to_insert) * UNFM_P_SIZE, GFP_ATOMIC); // We need to avoid scheduling. |
932 | if (!un) { | 933 | if (!un) { |
933 | un = &unf_single; | 934 | un = &unf_single; |
934 | blocks_needed = 1; | 935 | blocks_needed = 1; |
935 | max_to_insert = 0; | 936 | max_to_insert = 0; |
936 | } else | 937 | } |
937 | memset(un, 0, | ||
938 | UNFM_P_SIZE * min(blocks_needed, | ||
939 | max_to_insert)); | ||
940 | } | 938 | } |
941 | if (blocks_needed <= max_to_insert) { | 939 | if (blocks_needed <= max_to_insert) { |
942 | /* we are going to add target block to the file. Use allocated | 940 | /* we are going to add target block to the file. Use allocated |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 85ce23268302..7280a23ef344 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -104,7 +104,7 @@ static int release_journal_dev(struct super_block *super, | |||
104 | struct reiserfs_journal *journal); | 104 | struct reiserfs_journal *journal); |
105 | static int dirty_one_transaction(struct super_block *s, | 105 | static int dirty_one_transaction(struct super_block *s, |
106 | struct reiserfs_journal_list *jl); | 106 | struct reiserfs_journal_list *jl); |
107 | static void flush_async_commits(void *p); | 107 | static void flush_async_commits(struct work_struct *work); |
108 | static void queue_log_writer(struct super_block *s); | 108 | static void queue_log_writer(struct super_block *s); |
109 | 109 | ||
110 | /* values for join in do_journal_begin_r */ | 110 | /* values for join in do_journal_begin_r */ |
@@ -1464,7 +1464,7 @@ static int flush_journal_list(struct super_block *s, | |||
1464 | } | 1464 | } |
1465 | 1465 | ||
1466 | /* if someone has this block in a newer transaction, just make | 1466 | /* if someone has this block in a newer transaction, just make |
1467 | ** sure they are commited, and don't try writing it to disk | 1467 | ** sure they are committed, and don't try writing it to disk |
1468 | */ | 1468 | */ |
1469 | if (pjl) { | 1469 | if (pjl) { |
1470 | if (atomic_read(&pjl->j_commit_left)) | 1470 | if (atomic_read(&pjl->j_commit_left)) |
@@ -2836,7 +2836,8 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, | |||
2836 | if (reiserfs_mounted_fs_count <= 1) | 2836 | if (reiserfs_mounted_fs_count <= 1) |
2837 | commit_wq = create_workqueue("reiserfs"); | 2837 | commit_wq = create_workqueue("reiserfs"); |
2838 | 2838 | ||
2839 | INIT_WORK(&journal->j_work, flush_async_commits, p_s_sb); | 2839 | INIT_DELAYED_WORK(&journal->j_work, flush_async_commits); |
2840 | journal->j_work_sb = p_s_sb; | ||
2840 | return 0; | 2841 | return 0; |
2841 | free_and_return: | 2842 | free_and_return: |
2842 | free_journal_ram(p_s_sb); | 2843 | free_journal_ram(p_s_sb); |
@@ -3384,7 +3385,7 @@ static int remove_from_transaction(struct super_block *p_s_sb, | |||
3384 | 3385 | ||
3385 | /* | 3386 | /* |
3386 | ** for any cnode in a journal list, it can only be dirtied of all the | 3387 | ** for any cnode in a journal list, it can only be dirtied of all the |
3387 | ** transactions that include it are commited to disk. | 3388 | ** transactions that include it are committed to disk. |
3388 | ** this checks through each transaction, and returns 1 if you are allowed to dirty, | 3389 | ** this checks through each transaction, and returns 1 if you are allowed to dirty, |
3389 | ** and 0 if you aren't | 3390 | ** and 0 if you aren't |
3390 | ** | 3391 | ** |
@@ -3426,7 +3427,7 @@ static int can_dirty(struct reiserfs_journal_cnode *cn) | |||
3426 | } | 3427 | } |
3427 | 3428 | ||
3428 | /* syncs the commit blocks, but does not force the real buffers to disk | 3429 | /* syncs the commit blocks, but does not force the real buffers to disk |
3429 | ** will wait until the current transaction is done/commited before returning | 3430 | ** will wait until the current transaction is done/committed before returning |
3430 | */ | 3431 | */ |
3431 | int journal_end_sync(struct reiserfs_transaction_handle *th, | 3432 | int journal_end_sync(struct reiserfs_transaction_handle *th, |
3432 | struct super_block *p_s_sb, unsigned long nblocks) | 3433 | struct super_block *p_s_sb, unsigned long nblocks) |
@@ -3447,10 +3448,11 @@ int journal_end_sync(struct reiserfs_transaction_handle *th, | |||
3447 | /* | 3448 | /* |
3448 | ** writeback the pending async commits to disk | 3449 | ** writeback the pending async commits to disk |
3449 | */ | 3450 | */ |
3450 | static void flush_async_commits(void *p) | 3451 | static void flush_async_commits(struct work_struct *work) |
3451 | { | 3452 | { |
3452 | struct super_block *p_s_sb = p; | 3453 | struct reiserfs_journal *journal = |
3453 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); | 3454 | container_of(work, struct reiserfs_journal, j_work.work); |
3455 | struct super_block *p_s_sb = journal->j_work_sb; | ||
3454 | struct reiserfs_journal_list *jl; | 3456 | struct reiserfs_journal_list *jl; |
3455 | struct list_head *entry; | 3457 | struct list_head *entry; |
3456 | 3458 | ||
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 17249994110f..7fb5fb036f90 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -490,13 +490,13 @@ static void reiserfs_put_super(struct super_block *s) | |||
490 | return; | 490 | return; |
491 | } | 491 | } |
492 | 492 | ||
493 | static kmem_cache_t *reiserfs_inode_cachep; | 493 | static struct kmem_cache *reiserfs_inode_cachep; |
494 | 494 | ||
495 | static struct inode *reiserfs_alloc_inode(struct super_block *sb) | 495 | static struct inode *reiserfs_alloc_inode(struct super_block *sb) |
496 | { | 496 | { |
497 | struct reiserfs_inode_info *ei; | 497 | struct reiserfs_inode_info *ei; |
498 | ei = (struct reiserfs_inode_info *) | 498 | ei = (struct reiserfs_inode_info *) |
499 | kmem_cache_alloc(reiserfs_inode_cachep, SLAB_KERNEL); | 499 | kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL); |
500 | if (!ei) | 500 | if (!ei) |
501 | return NULL; | 501 | return NULL; |
502 | return &ei->vfs_inode; | 502 | return &ei->vfs_inode; |
@@ -507,7 +507,7 @@ static void reiserfs_destroy_inode(struct inode *inode) | |||
507 | kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode)); | 507 | kmem_cache_free(reiserfs_inode_cachep, REISERFS_I(inode)); |
508 | } | 508 | } |
509 | 509 | ||
510 | static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) | 510 | static void init_once(void *foo, struct kmem_cache * cachep, unsigned long flags) |
511 | { | 511 | { |
512 | struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; | 512 | struct reiserfs_inode_info *ei = (struct reiserfs_inode_info *)foo; |
513 | 513 | ||
@@ -1549,13 +1549,12 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1549 | struct reiserfs_sb_info *sbi; | 1549 | struct reiserfs_sb_info *sbi; |
1550 | int errval = -EINVAL; | 1550 | int errval = -EINVAL; |
1551 | 1551 | ||
1552 | sbi = kmalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); | 1552 | sbi = kzalloc(sizeof(struct reiserfs_sb_info), GFP_KERNEL); |
1553 | if (!sbi) { | 1553 | if (!sbi) { |
1554 | errval = -ENOMEM; | 1554 | errval = -ENOMEM; |
1555 | goto error; | 1555 | goto error; |
1556 | } | 1556 | } |
1557 | s->s_fs_info = sbi; | 1557 | s->s_fs_info = sbi; |
1558 | memset(sbi, 0, sizeof(struct reiserfs_sb_info)); | ||
1559 | /* Set default values for options: non-aggressive tails, RO on errors */ | 1558 | /* Set default values for options: non-aggressive tails, RO on errors */ |
1560 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); | 1559 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_SMALLTAIL); |
1561 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO); | 1560 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ERROR_RO); |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 7bdb0ed443e1..1e4d68590178 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include <linux/reiserfs_xattr.h> | 41 | #include <linux/reiserfs_xattr.h> |
42 | #include <linux/reiserfs_acl.h> | 42 | #include <linux/reiserfs_acl.h> |
43 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | #include <asm/checksum.h> | 44 | #include <net/checksum.h> |
45 | #include <linux/smp_lock.h> | 45 | #include <linux/smp_lock.h> |
46 | #include <linux/stat.h> | 46 | #include <linux/stat.h> |
47 | #include <asm/semaphore.h> | 47 | #include <asm/semaphore.h> |
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c index ddcd9e1ef282..c5af088d4a4c 100644 --- a/fs/romfs/inode.c +++ b/fs/romfs/inode.c | |||
@@ -550,12 +550,12 @@ romfs_read_inode(struct inode *i) | |||
550 | } | 550 | } |
551 | } | 551 | } |
552 | 552 | ||
553 | static kmem_cache_t * romfs_inode_cachep; | 553 | static struct kmem_cache * romfs_inode_cachep; |
554 | 554 | ||
555 | static struct inode *romfs_alloc_inode(struct super_block *sb) | 555 | static struct inode *romfs_alloc_inode(struct super_block *sb) |
556 | { | 556 | { |
557 | struct romfs_inode_info *ei; | 557 | struct romfs_inode_info *ei; |
558 | ei = (struct romfs_inode_info *)kmem_cache_alloc(romfs_inode_cachep, SLAB_KERNEL); | 558 | ei = (struct romfs_inode_info *)kmem_cache_alloc(romfs_inode_cachep, GFP_KERNEL); |
559 | if (!ei) | 559 | if (!ei) |
560 | return NULL; | 560 | return NULL; |
561 | return &ei->vfs_inode; | 561 | return &ei->vfs_inode; |
@@ -566,7 +566,7 @@ static void romfs_destroy_inode(struct inode *inode) | |||
566 | kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); | 566 | kmem_cache_free(romfs_inode_cachep, ROMFS_I(inode)); |
567 | } | 567 | } |
568 | 568 | ||
569 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 569 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
570 | { | 570 | { |
571 | struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; | 571 | struct romfs_inode_info *ei = (struct romfs_inode_info *) foo; |
572 | 572 | ||
diff --git a/fs/seq_file.c b/fs/seq_file.c index 555b9ac04c25..10690aa401c7 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -26,7 +26,7 @@ | |||
26 | * ERR_PTR(error). In the end of sequence they return %NULL. ->show() | 26 | * ERR_PTR(error). In the end of sequence they return %NULL. ->show() |
27 | * returns 0 in case of success and negative number in case of error. | 27 | * returns 0 in case of success and negative number in case of error. |
28 | */ | 28 | */ |
29 | int seq_open(struct file *file, struct seq_operations *op) | 29 | int seq_open(struct file *file, const struct seq_operations *op) |
30 | { | 30 | { |
31 | struct seq_file *p = file->private_data; | 31 | struct seq_file *p = file->private_data; |
32 | 32 | ||
@@ -408,7 +408,7 @@ EXPORT_SYMBOL(single_open); | |||
408 | 408 | ||
409 | int single_release(struct inode *inode, struct file *file) | 409 | int single_release(struct inode *inode, struct file *file) |
410 | { | 410 | { |
411 | struct seq_operations *op = ((struct seq_file *)file->private_data)->op; | 411 | const struct seq_operations *op = ((struct seq_file *)file->private_data)->op; |
412 | int res = seq_release(inode, file); | 412 | int res = seq_release(inode, file); |
413 | kfree(op); | 413 | kfree(op); |
414 | return res; | 414 | return res; |
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 2c122ee83adb..4af4cd729a5a 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -50,12 +50,12 @@ static void smb_put_super(struct super_block *); | |||
50 | static int smb_statfs(struct dentry *, struct kstatfs *); | 50 | static int smb_statfs(struct dentry *, struct kstatfs *); |
51 | static int smb_show_options(struct seq_file *, struct vfsmount *); | 51 | static int smb_show_options(struct seq_file *, struct vfsmount *); |
52 | 52 | ||
53 | static kmem_cache_t *smb_inode_cachep; | 53 | static struct kmem_cache *smb_inode_cachep; |
54 | 54 | ||
55 | static struct inode *smb_alloc_inode(struct super_block *sb) | 55 | static struct inode *smb_alloc_inode(struct super_block *sb) |
56 | { | 56 | { |
57 | struct smb_inode_info *ei; | 57 | struct smb_inode_info *ei; |
58 | ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, SLAB_KERNEL); | 58 | ei = (struct smb_inode_info *)kmem_cache_alloc(smb_inode_cachep, GFP_KERNEL); |
59 | if (!ei) | 59 | if (!ei) |
60 | return NULL; | 60 | return NULL; |
61 | return &ei->vfs_inode; | 61 | return &ei->vfs_inode; |
@@ -66,7 +66,7 @@ static void smb_destroy_inode(struct inode *inode) | |||
66 | kmem_cache_free(smb_inode_cachep, SMB_I(inode)); | 66 | kmem_cache_free(smb_inode_cachep, SMB_I(inode)); |
67 | } | 67 | } |
68 | 68 | ||
69 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 69 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
70 | { | 70 | { |
71 | struct smb_inode_info *ei = (struct smb_inode_info *) foo; | 71 | struct smb_inode_info *ei = (struct smb_inode_info *) foo; |
72 | unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; | 72 | unsigned long flagmask = SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR; |
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c index 0fb74697abc4..a4bcae8a9aff 100644 --- a/fs/smbfs/request.c +++ b/fs/smbfs/request.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #define ROUND_UP(x) (((x)+3) & ~3) | 25 | #define ROUND_UP(x) (((x)+3) & ~3) |
26 | 26 | ||
27 | /* cache for request structures */ | 27 | /* cache for request structures */ |
28 | static kmem_cache_t *req_cachep; | 28 | static struct kmem_cache *req_cachep; |
29 | 29 | ||
30 | static int smb_request_send_req(struct smb_request *req); | 30 | static int smb_request_send_req(struct smb_request *req); |
31 | 31 | ||
@@ -61,7 +61,7 @@ static struct smb_request *smb_do_alloc_request(struct smb_sb_info *server, | |||
61 | struct smb_request *req; | 61 | struct smb_request *req; |
62 | unsigned char *buf = NULL; | 62 | unsigned char *buf = NULL; |
63 | 63 | ||
64 | req = kmem_cache_alloc(req_cachep, SLAB_KERNEL); | 64 | req = kmem_cache_alloc(req_cachep, GFP_KERNEL); |
65 | VERBOSE("allocating request: %p\n", req); | 65 | VERBOSE("allocating request: %p\n", req); |
66 | if (!req) | 66 | if (!req) |
67 | goto out; | 67 | goto out; |
@@ -51,13 +51,6 @@ int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
51 | return inode->i_op->getattr(mnt, dentry, stat); | 51 | return inode->i_op->getattr(mnt, dentry, stat); |
52 | 52 | ||
53 | generic_fillattr(inode, stat); | 53 | generic_fillattr(inode, stat); |
54 | if (!stat->blksize) { | ||
55 | struct super_block *s = inode->i_sb; | ||
56 | unsigned blocks; | ||
57 | blocks = (stat->size+s->s_blocksize-1) >> s->s_blocksize_bits; | ||
58 | stat->blocks = (s->s_blocksize / 512) * blocks; | ||
59 | stat->blksize = s->s_blocksize; | ||
60 | } | ||
61 | return 0; | 54 | return 0; |
62 | } | 55 | } |
63 | 56 | ||
diff --git a/fs/super.c b/fs/super.c index 47e554c12e76..84c320f6ad7e 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -221,6 +221,24 @@ static int grab_super(struct super_block *s) __releases(sb_lock) | |||
221 | } | 221 | } |
222 | 222 | ||
223 | /* | 223 | /* |
224 | * Superblock locking. We really ought to get rid of these two. | ||
225 | */ | ||
226 | void lock_super(struct super_block * sb) | ||
227 | { | ||
228 | get_fs_excl(); | ||
229 | mutex_lock(&sb->s_lock); | ||
230 | } | ||
231 | |||
232 | void unlock_super(struct super_block * sb) | ||
233 | { | ||
234 | put_fs_excl(); | ||
235 | mutex_unlock(&sb->s_lock); | ||
236 | } | ||
237 | |||
238 | EXPORT_SYMBOL(lock_super); | ||
239 | EXPORT_SYMBOL(unlock_super); | ||
240 | |||
241 | /* | ||
224 | * Write out and wait upon all dirty data associated with this | 242 | * Write out and wait upon all dirty data associated with this |
225 | * superblock. Filesystem data as well as the underlying block | 243 | * superblock. Filesystem data as well as the underlying block |
226 | * device. Takes the superblock lock. Requires a second blkdev | 244 | * device. Takes the superblock lock. Requires a second blkdev |
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/file.h> | 6 | #include <linux/file.h> |
7 | #include <linux/fs.h> | 7 | #include <linux/fs.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/sched.h> | ||
9 | #include <linux/writeback.h> | 10 | #include <linux/writeback.h> |
10 | #include <linux/syscalls.h> | 11 | #include <linux/syscalls.h> |
11 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index 3aa3434621ca..a5782e8c7f07 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -372,6 +372,51 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name) | |||
372 | return error; | 372 | return error; |
373 | } | 373 | } |
374 | 374 | ||
375 | int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent) | ||
376 | { | ||
377 | struct dentry *old_parent_dentry, *new_parent_dentry, *new_dentry; | ||
378 | struct sysfs_dirent *new_parent_sd, *sd; | ||
379 | int error; | ||
380 | |||
381 | if (!new_parent) | ||
382 | return -EINVAL; | ||
383 | |||
384 | old_parent_dentry = kobj->parent ? | ||
385 | kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; | ||
386 | new_parent_dentry = new_parent->dentry; | ||
387 | |||
388 | again: | ||
389 | mutex_lock(&old_parent_dentry->d_inode->i_mutex); | ||
390 | if (!mutex_trylock(&new_parent_dentry->d_inode->i_mutex)) { | ||
391 | mutex_unlock(&old_parent_dentry->d_inode->i_mutex); | ||
392 | goto again; | ||
393 | } | ||
394 | |||
395 | new_parent_sd = new_parent_dentry->d_fsdata; | ||
396 | sd = kobj->dentry->d_fsdata; | ||
397 | |||
398 | new_dentry = lookup_one_len(kobj->name, new_parent_dentry, | ||
399 | strlen(kobj->name)); | ||
400 | if (IS_ERR(new_dentry)) { | ||
401 | error = PTR_ERR(new_dentry); | ||
402 | goto out; | ||
403 | } else | ||
404 | error = 0; | ||
405 | d_add(new_dentry, NULL); | ||
406 | d_move(kobj->dentry, new_dentry); | ||
407 | dput(new_dentry); | ||
408 | |||
409 | /* Remove from old parent's list and insert into new parent's list. */ | ||
410 | list_del_init(&sd->s_sibling); | ||
411 | list_add(&sd->s_sibling, &new_parent_sd->s_children); | ||
412 | |||
413 | out: | ||
414 | mutex_unlock(&new_parent_dentry->d_inode->i_mutex); | ||
415 | mutex_unlock(&old_parent_dentry->d_inode->i_mutex); | ||
416 | |||
417 | return error; | ||
418 | } | ||
419 | |||
375 | static int sysfs_dir_open(struct inode *inode, struct file *file) | 420 | static int sysfs_dir_open(struct inode *inode, struct file *file) |
376 | { | 421 | { |
377 | struct dentry * dentry = file->f_dentry; | 422 | struct dentry * dentry = file->f_dentry; |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 298303b5a716..95c165101c98 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -190,6 +190,9 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t | |||
190 | count = PAGE_SIZE - 1; | 190 | count = PAGE_SIZE - 1; |
191 | error = copy_from_user(buffer->page,buf,count); | 191 | error = copy_from_user(buffer->page,buf,count); |
192 | buffer->needs_read_fill = 1; | 192 | buffer->needs_read_fill = 1; |
193 | /* if buf is assumed to contain a string, terminate it by \0, | ||
194 | so e.g. sscanf() can scan the string easily */ | ||
195 | buffer->page[count] = 0; | ||
193 | return error ? -EFAULT : count; | 196 | return error ? -EFAULT : count; |
194 | } | 197 | } |
195 | 198 | ||
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 20551a1b8a56..e503f858fba8 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | struct vfsmount *sysfs_mount; | 17 | struct vfsmount *sysfs_mount; |
18 | struct super_block * sysfs_sb = NULL; | 18 | struct super_block * sysfs_sb = NULL; |
19 | kmem_cache_t *sysfs_dir_cachep; | 19 | struct kmem_cache *sysfs_dir_cachep; |
20 | 20 | ||
21 | static struct super_operations sysfs_ops = { | 21 | static struct super_operations sysfs_ops = { |
22 | .statfs = simple_statfs, | 22 | .statfs = simple_statfs, |
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index 6f3d6bd52887..bd7cec295dab 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 | ||
2 | extern struct vfsmount * sysfs_mount; | 2 | extern struct vfsmount * sysfs_mount; |
3 | extern kmem_cache_t *sysfs_dir_cachep; | 3 | extern struct kmem_cache *sysfs_dir_cachep; |
4 | 4 | ||
5 | extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); | 5 | extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); |
6 | extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); | 6 | extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); |
diff --git a/fs/sysv/CHANGES b/fs/sysv/CHANGES deleted file mode 100644 index 66ea6e92be66..000000000000 --- a/fs/sysv/CHANGES +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | Mon, 15 Dec 1997 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> | ||
2 | * namei.c: struct sysv_dir_inode_operations updated to use dentries. | ||
3 | |||
4 | Fri, 23 Jan 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> | ||
5 | * inode.c: corrected 1 track offset setting (in sb->sv_block_base). | ||
6 | Originally it was overridden (by setting to zero) | ||
7 | in detected_[xenix,sysv4,sysv2,coherent]. Thanks | ||
8 | to Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl> | ||
9 | for identifying the problem. | ||
10 | |||
11 | Tue, 27 Jan 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> | ||
12 | * inode.c: added 2048-byte block support to SystemV FS. | ||
13 | Merged detected_bs[512,1024,2048]() into one function: | ||
14 | void detected_bs (u_char type, struct super_block *sb). | ||
15 | Thanks to Andrzej Krzysztofowicz <ankry@mif.pg.gda.pl> | ||
16 | for the patch. | ||
17 | |||
18 | Wed, 4 Feb 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> | ||
19 | * namei.c: removed static subdir(); is_subdir() from dcache.c | ||
20 | is used instead. Cosmetic changes. | ||
21 | |||
22 | Thu, 3 Dec 1998 Al Viro (viro@parcelfarce.linux.theplanet.co.uk) | ||
23 | * namei.c (sysv_rmdir): | ||
24 | Bugectomy: old check for victim being busy | ||
25 | (inode->i_count) wasn't replaced (with checking | ||
26 | dentry->d_count) and escaped Linus in the last round | ||
27 | of changes. Shot and buried. | ||
28 | |||
29 | Wed, 9 Dec 1998 AV | ||
30 | * namei.c (do_sysv_rename): | ||
31 | Fixed incorrect check for other owners + race. | ||
32 | Removed checks that went to VFS. | ||
33 | * namei.c (sysv_unlink): | ||
34 | Removed checks that went to VFS. | ||
35 | |||
36 | Thu, 10 Dec 1998 AV | ||
37 | * namei.c (do_mknod): | ||
38 | Removed dead code - mknod is never asked to | ||
39 | create a symlink or directory. Incidentially, | ||
40 | it wouldn't do it right if it would be called. | ||
41 | |||
42 | Sat, 26 Dec 1998 KGB | ||
43 | * inode.c (detect_sysv4): | ||
44 | Added detection of expanded s_type field (0x10, | ||
45 | 0x20 and 0x30). Forced read-only access in this case. | ||
46 | |||
47 | Sun, 21 Mar 1999 AV | ||
48 | * namei.c (sysv_link): | ||
49 | Fixed i_count usage that resulted in dcache corruption. | ||
50 | * inode.c: | ||
51 | Filled ->delete_inode() method with sysv_delete_inode(). | ||
52 | sysv_put_inode() is gone, as it tried to do ->delete_ | ||
53 | _inode()'s job. | ||
54 | * ialloc.c: (sysv_free_inode): | ||
55 | Fixed race. | ||
56 | |||
57 | Sun, 30 Apr 1999 AV | ||
58 | * namei.c (sysv_mknod): | ||
59 | Removed dead code (S_IFREG case is now passed to | ||
60 | ->create() by VFS). | ||
diff --git a/fs/sysv/ChangeLog b/fs/sysv/ChangeLog deleted file mode 100644 index f403f8b91b80..000000000000 --- a/fs/sysv/ChangeLog +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | Thu Feb 14 2002 Andrew Morton <akpm@zip.com.au> | ||
2 | |||
3 | * dir_commit_chunk(): call writeout_one_page() as well as | ||
4 | waitfor_one_page() for IS_SYNC directories, so that we | ||
5 | actually do sync the directory. (forward-port from 2.4). | ||
6 | |||
7 | Thu Feb 7 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
8 | |||
9 | * super.c: switched to ->get_sb() | ||
10 | * ChangeLog: fixed dates ;-) | ||
11 | |||
12 | 2002-01-24 David S. Miller <davem@redhat.com> | ||
13 | |||
14 | * inode.c: Include linux/init.h | ||
15 | |||
16 | Mon Jan 21 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
17 | * ialloc.c (sysv_new_inode): zero SYSV_I(inode)->i_data out. | ||
18 | * i_vnode renamed to vfs_inode. Sorry, but let's keep that | ||
19 | consistent. | ||
20 | |||
21 | Sat Jan 19 2002 Christoph Hellwig <hch@infradead.org> | ||
22 | |||
23 | * include/linux/sysv_fs.h (SYSV_I): Get fs-private inode data using | ||
24 | list_entry() instead of inode->u. | ||
25 | * include/linux/sysv_fs_i.h: Add 'struct inode i_vnode' field to | ||
26 | sysv_inode_info structure. | ||
27 | * inode.c: Include <linux/slab.h>, implement alloc_inode/destroy_inode | ||
28 | sop methods, add infrastructure for per-fs inode slab cache. | ||
29 | * super.c (init_sysv_fs): Initialize inode cache, recover properly | ||
30 | in the case of failed register_filesystem for V7. | ||
31 | (exit_sysv_fs): Destroy inode cache. | ||
32 | |||
33 | Sat Jan 19 2002 Christoph Hellwig <hch@infradead.org> | ||
34 | |||
35 | * include/linux/sysv_fs.h: Include <linux/sysv_fs_i.h>, declare SYSV_I(). | ||
36 | * dir.c (sysv_find_entry): Use SYSV_I() instead of ->u.sysv_i to | ||
37 | access fs-private inode data. | ||
38 | * ialloc.c (sysv_new_inode): Likewise. | ||
39 | * inode.c (sysv_read_inode): Likewise. | ||
40 | (sysv_update_inode): Likewise. | ||
41 | * itree.c (get_branch): Likewise. | ||
42 | (sysv_truncate): Likewise. | ||
43 | * symlink.c (sysv_readlink): Likewise. | ||
44 | (sysv_follow_link): Likewise. | ||
45 | |||
46 | Fri Jan 4 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
47 | |||
48 | * ialloc.c (sysv_free_inode): Use sb->s_id instead of bdevname(). | ||
49 | * inode.c (sysv_read_inode): Likewise. | ||
50 | (sysv_update_inode): Likewise. | ||
51 | (sysv_sync_inode): Likewise. | ||
52 | * super.c (detect_sysv): Likewise. | ||
53 | (complete_read_super): Likewise. | ||
54 | (sysv_read_super): Likewise. | ||
55 | (v7_read_super): Likewise. | ||
56 | |||
57 | Sun Dec 30 2001 Manfred Spraul <manfred@colorfullife.com> | ||
58 | |||
59 | * dir.c (dir_commit_chunk): Do not set dir->i_version. | ||
60 | (sysv_readdir): Likewise. | ||
61 | |||
62 | Thu Dec 27 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
63 | |||
64 | * itree.c (get_block): Use map_bh() to fill out bh_result. | ||
65 | |||
66 | Tue Dec 25 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
67 | |||
68 | * super.c (sysv_read_super): Use sb_set_blocksize() to set blocksize. | ||
69 | (v7_read_super): Likewise. | ||
70 | |||
71 | Tue Nov 27 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | ||
72 | |||
73 | * itree.c (get_block): Change type for iblock argument to sector_t. | ||
74 | * super.c (sysv_read_super): Set s_blocksize early. | ||
75 | (v7_read_super): Likewise. | ||
76 | * balloc.c (sysv_new_block): Use sb_bread(). instead of bread(). | ||
77 | (sysv_count_free_blocks): Likewise. | ||
78 | * ialloc.c (sysv_raw_inode): Likewise. | ||
79 | * itree.c (get_branch): Likewise. | ||
80 | (free_branches): Likewise. | ||
81 | * super.c (sysv_read_super): Likewise. | ||
82 | (v7_read_super): Likewise. | ||
83 | |||
84 | Sat Dec 15 2001 Christoph Hellwig <hch@infradead.org> | ||
85 | |||
86 | * inode.c (sysv_read_inode): Mark inode as bad in case of failure. | ||
87 | * super.c (complete_read_super): Check for bad root inode. | ||
88 | |||
89 | Wed Nov 21 2001 Andrew Morton <andrewm@uow.edu.au> | ||
90 | |||
91 | * file.c (sysv_sync_file): Call fsync_inode_data_buffers. | ||
92 | |||
93 | Fri Oct 26 2001 Christoph Hellwig <hch@infradead.org> | ||
94 | |||
95 | * dir.c, ialloc.c, namei.c, include/linux/sysv_fs_i.h: | ||
96 | Implement per-Inode lookup offset cache. | ||
97 | Modelled after Ted's ext2 patch. | ||
98 | |||
99 | Fri Oct 26 2001 Christoph Hellwig <hch@infradead.org> | ||
100 | |||
101 | * inode.c, super.c, include/linux/sysv_fs.h, | ||
102 | include/linux/sysv_fs_sb.h: | ||
103 | Remove symlink faking. Noone really wants to use these as | ||
104 | linux filesystems and native OSes don't support it anyway. | ||
105 | |||
106 | |||
diff --git a/fs/sysv/INTRO b/fs/sysv/INTRO deleted file mode 100644 index de4e4d17cac6..000000000000 --- a/fs/sysv/INTRO +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | This is the implementation of the SystemV/Coherent filesystem for Linux. | ||
2 | It grew out of separate filesystem implementations | ||
3 | |||
4 | Xenix FS Doug Evans <dje@cygnus.com> June 1992 | ||
5 | SystemV FS Paul B. Monday <pmonday@eecs.wsu.edu> March-June 1993 | ||
6 | Coherent FS B. Haible <haible@ma2s2.mathematik.uni-karlsruhe.de> June 1993 | ||
7 | |||
8 | and was merged together in July 1993. | ||
9 | |||
10 | These filesystems are rather similar. Here is a comparison with Minix FS: | ||
11 | |||
12 | * Linux fdisk reports on partitions | ||
13 | - Minix FS 0x81 Linux/Minix | ||
14 | - Xenix FS ?? | ||
15 | - SystemV FS ?? | ||
16 | - Coherent FS 0x08 AIX bootable | ||
17 | |||
18 | * Size of a block or zone (data allocation unit on disk) | ||
19 | - Minix FS 1024 | ||
20 | - Xenix FS 1024 (also 512 ??) | ||
21 | - SystemV FS 1024 (also 512 and 2048) | ||
22 | - Coherent FS 512 | ||
23 | |||
24 | * General layout: all have one boot block, one super block and | ||
25 | separate areas for inodes and for directories/data. | ||
26 | On SystemV Release 2 FS (e.g. Microport) the first track is reserved and | ||
27 | all the block numbers (including the super block) are offset by one track. | ||
28 | |||
29 | * Byte ordering of "short" (16 bit entities) on disk: | ||
30 | - Minix FS little endian 0 1 | ||
31 | - Xenix FS little endian 0 1 | ||
32 | - SystemV FS little endian 0 1 | ||
33 | - Coherent FS little endian 0 1 | ||
34 | Of course, this affects only the file system, not the data of files on it! | ||
35 | |||
36 | * Byte ordering of "long" (32 bit entities) on disk: | ||
37 | - Minix FS little endian 0 1 2 3 | ||
38 | - Xenix FS little endian 0 1 2 3 | ||
39 | - SystemV FS little endian 0 1 2 3 | ||
40 | - Coherent FS PDP-11 2 3 0 1 | ||
41 | Of course, this affects only the file system, not the data of files on it! | ||
42 | |||
43 | * Inode on disk: "short", 0 means non-existent, the root dir ino is: | ||
44 | - Minix FS 1 | ||
45 | - Xenix FS, SystemV FS, Coherent FS 2 | ||
46 | |||
47 | * Maximum number of hard links to a file: | ||
48 | - Minix FS 250 | ||
49 | - Xenix FS ?? | ||
50 | - SystemV FS ?? | ||
51 | - Coherent FS >=10000 | ||
52 | |||
53 | * Free inode management: | ||
54 | - Minix FS a bitmap | ||
55 | - Xenix FS, SystemV FS, Coherent FS | ||
56 | There is a cache of a certain number of free inodes in the super-block. | ||
57 | When it is exhausted, new free inodes are found using a linear search. | ||
58 | |||
59 | * Free block management: | ||
60 | - Minix FS a bitmap | ||
61 | - Xenix FS, SystemV FS, Coherent FS | ||
62 | Free blocks are organized in a "free list". Maybe a misleading term, | ||
63 | since it is not true that every free block contains a pointer to | ||
64 | the next free block. Rather, the free blocks are organized in chunks | ||
65 | of limited size, and every now and then a free block contains pointers | ||
66 | to the free blocks pertaining to the next chunk; the first of these | ||
67 | contains pointers and so on. The list terminates with a "block number" | ||
68 | 0 on Xenix FS and SystemV FS, with a block zeroed out on Coherent FS. | ||
69 | |||
70 | * Super-block location: | ||
71 | - Minix FS block 1 = bytes 1024..2047 | ||
72 | - Xenix FS block 1 = bytes 1024..2047 | ||
73 | - SystemV FS bytes 512..1023 | ||
74 | - Coherent FS block 1 = bytes 512..1023 | ||
75 | |||
76 | * Super-block layout: | ||
77 | - Minix FS | ||
78 | unsigned short s_ninodes; | ||
79 | unsigned short s_nzones; | ||
80 | unsigned short s_imap_blocks; | ||
81 | unsigned short s_zmap_blocks; | ||
82 | unsigned short s_firstdatazone; | ||
83 | unsigned short s_log_zone_size; | ||
84 | unsigned long s_max_size; | ||
85 | unsigned short s_magic; | ||
86 | - Xenix FS, SystemV FS, Coherent FS | ||
87 | unsigned short s_firstdatazone; | ||
88 | unsigned long s_nzones; | ||
89 | unsigned short s_fzone_count; | ||
90 | unsigned long s_fzones[NICFREE]; | ||
91 | unsigned short s_finode_count; | ||
92 | unsigned short s_finodes[NICINOD]; | ||
93 | char s_flock; | ||
94 | char s_ilock; | ||
95 | char s_modified; | ||
96 | char s_rdonly; | ||
97 | unsigned long s_time; | ||
98 | short s_dinfo[4]; -- SystemV FS only | ||
99 | unsigned long s_free_zones; | ||
100 | unsigned short s_free_inodes; | ||
101 | short s_dinfo[4]; -- Xenix FS only | ||
102 | unsigned short s_interleave_m,s_interleave_n; -- Coherent FS only | ||
103 | char s_fname[6]; | ||
104 | char s_fpack[6]; | ||
105 | then they differ considerably: | ||
106 | Xenix FS | ||
107 | char s_clean; | ||
108 | char s_fill[371]; | ||
109 | long s_magic; | ||
110 | long s_type; | ||
111 | SystemV FS | ||
112 | long s_fill[12 or 14]; | ||
113 | long s_state; | ||
114 | long s_magic; | ||
115 | long s_type; | ||
116 | Coherent FS | ||
117 | unsigned long s_unique; | ||
118 | Note that Coherent FS has no magic. | ||
119 | |||
120 | * Inode layout: | ||
121 | - Minix FS | ||
122 | unsigned short i_mode; | ||
123 | unsigned short i_uid; | ||
124 | unsigned long i_size; | ||
125 | unsigned long i_time; | ||
126 | unsigned char i_gid; | ||
127 | unsigned char i_nlinks; | ||
128 | unsigned short i_zone[7+1+1]; | ||
129 | - Xenix FS, SystemV FS, Coherent FS | ||
130 | unsigned short i_mode; | ||
131 | unsigned short i_nlink; | ||
132 | unsigned short i_uid; | ||
133 | unsigned short i_gid; | ||
134 | unsigned long i_size; | ||
135 | unsigned char i_zone[3*(10+1+1+1)]; | ||
136 | unsigned long i_atime; | ||
137 | unsigned long i_mtime; | ||
138 | unsigned long i_ctime; | ||
139 | |||
140 | * Regular file data blocks are organized as | ||
141 | - Minix FS | ||
142 | 7 direct blocks | ||
143 | 1 indirect block (pointers to blocks) | ||
144 | 1 double-indirect block (pointer to pointers to blocks) | ||
145 | - Xenix FS, SystemV FS, Coherent FS | ||
146 | 10 direct blocks | ||
147 | 1 indirect block (pointers to blocks) | ||
148 | 1 double-indirect block (pointer to pointers to blocks) | ||
149 | 1 triple-indirect block (pointer to pointers to pointers to blocks) | ||
150 | |||
151 | * Inode size, inodes per block | ||
152 | - Minix FS 32 32 | ||
153 | - Xenix FS 64 16 | ||
154 | - SystemV FS 64 16 | ||
155 | - Coherent FS 64 8 | ||
156 | |||
157 | * Directory entry on disk | ||
158 | - Minix FS | ||
159 | unsigned short inode; | ||
160 | char name[14/30]; | ||
161 | - Xenix FS, SystemV FS, Coherent FS | ||
162 | unsigned short inode; | ||
163 | char name[14]; | ||
164 | |||
165 | * Dir entry size, dir entries per block | ||
166 | - Minix FS 16/32 64/32 | ||
167 | - Xenix FS 16 64 | ||
168 | - SystemV FS 16 64 | ||
169 | - Coherent FS 16 32 | ||
170 | |||
171 | * How to implement symbolic links such that the host fsck doesn't scream: | ||
172 | - Minix FS normal | ||
173 | - Xenix FS kludge: as regular files with chmod 1000 | ||
174 | - SystemV FS ?? | ||
175 | - Coherent FS kludge: as regular files with chmod 1000 | ||
176 | |||
177 | |||
178 | Notation: We often speak of a "block" but mean a zone (the allocation unit) | ||
179 | and not the disk driver's notion of "block". | ||
180 | |||
181 | |||
182 | Bruno Haible <haible@ma2s2.mathematik.uni-karlsruhe.de> | ||
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c index d63c5e48b050..ead9864567e3 100644 --- a/fs/sysv/inode.c +++ b/fs/sysv/inode.c | |||
@@ -301,13 +301,13 @@ static void sysv_delete_inode(struct inode *inode) | |||
301 | unlock_kernel(); | 301 | unlock_kernel(); |
302 | } | 302 | } |
303 | 303 | ||
304 | static kmem_cache_t *sysv_inode_cachep; | 304 | static struct kmem_cache *sysv_inode_cachep; |
305 | 305 | ||
306 | static struct inode *sysv_alloc_inode(struct super_block *sb) | 306 | static struct inode *sysv_alloc_inode(struct super_block *sb) |
307 | { | 307 | { |
308 | struct sysv_inode_info *si; | 308 | struct sysv_inode_info *si; |
309 | 309 | ||
310 | si = kmem_cache_alloc(sysv_inode_cachep, SLAB_KERNEL); | 310 | si = kmem_cache_alloc(sysv_inode_cachep, GFP_KERNEL); |
311 | if (!si) | 311 | if (!si) |
312 | return NULL; | 312 | return NULL; |
313 | return &si->vfs_inode; | 313 | return &si->vfs_inode; |
@@ -318,7 +318,7 @@ static void sysv_destroy_inode(struct inode *inode) | |||
318 | kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); | 318 | kmem_cache_free(sysv_inode_cachep, SYSV_I(inode)); |
319 | } | 319 | } |
320 | 320 | ||
321 | static void init_once(void *p, kmem_cache_t *cachep, unsigned long flags) | 321 | static void init_once(void *p, struct kmem_cache *cachep, unsigned long flags) |
322 | { | 322 | { |
323 | struct sysv_inode_info *si = (struct sysv_inode_info *)p; | 323 | struct sysv_inode_info *si = (struct sysv_inode_info *)p; |
324 | 324 | ||
diff --git a/fs/udf/super.c b/fs/udf/super.c index 1aea6a4f9a4a..1dbc2955f02e 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -107,12 +107,12 @@ static struct file_system_type udf_fstype = { | |||
107 | .fs_flags = FS_REQUIRES_DEV, | 107 | .fs_flags = FS_REQUIRES_DEV, |
108 | }; | 108 | }; |
109 | 109 | ||
110 | static kmem_cache_t * udf_inode_cachep; | 110 | static struct kmem_cache * udf_inode_cachep; |
111 | 111 | ||
112 | static struct inode *udf_alloc_inode(struct super_block *sb) | 112 | static struct inode *udf_alloc_inode(struct super_block *sb) |
113 | { | 113 | { |
114 | struct udf_inode_info *ei; | 114 | struct udf_inode_info *ei; |
115 | ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, SLAB_KERNEL); | 115 | ei = (struct udf_inode_info *)kmem_cache_alloc(udf_inode_cachep, GFP_KERNEL); |
116 | if (!ei) | 116 | if (!ei) |
117 | return NULL; | 117 | return NULL; |
118 | 118 | ||
@@ -130,7 +130,7 @@ static void udf_destroy_inode(struct inode *inode) | |||
130 | kmem_cache_free(udf_inode_cachep, UDF_I(inode)); | 130 | kmem_cache_free(udf_inode_cachep, UDF_I(inode)); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 133 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
134 | { | 134 | { |
135 | struct udf_inode_info *ei = (struct udf_inode_info *) foo; | 135 | struct udf_inode_info *ei = (struct udf_inode_info *) foo; |
136 | 136 | ||
@@ -1709,7 +1709,7 @@ void udf_error(struct super_block *sb, const char *function, | |||
1709 | sb->s_dirt = 1; | 1709 | sb->s_dirt = 1; |
1710 | } | 1710 | } |
1711 | va_start(args, fmt); | 1711 | va_start(args, fmt); |
1712 | vsprintf(error_buf, fmt, args); | 1712 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
1713 | va_end(args); | 1713 | va_end(args); |
1714 | printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n", | 1714 | printk (KERN_CRIT "UDF-fs error (device %s): %s: %s\n", |
1715 | sb->s_id, function, error_buf); | 1715 | sb->s_id, function, error_buf); |
@@ -1721,7 +1721,7 @@ void udf_warning(struct super_block *sb, const char *function, | |||
1721 | va_list args; | 1721 | va_list args; |
1722 | 1722 | ||
1723 | va_start (args, fmt); | 1723 | va_start (args, fmt); |
1724 | vsprintf(error_buf, fmt, args); | 1724 | vsnprintf(error_buf, sizeof(error_buf), fmt, args); |
1725 | va_end(args); | 1725 | va_end(args); |
1726 | printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n", | 1726 | printk(KERN_WARNING "UDF-fs warning (device %s): %s: %s\n", |
1727 | sb->s_id, function, error_buf); | 1727 | sb->s_id, function, error_buf); |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index ec79e3091d1b..8a8e9382ec09 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
@@ -224,7 +224,7 @@ void ufs_error (struct super_block * sb, const char * function, | |||
224 | sb->s_flags |= MS_RDONLY; | 224 | sb->s_flags |= MS_RDONLY; |
225 | } | 225 | } |
226 | va_start (args, fmt); | 226 | va_start (args, fmt); |
227 | vsprintf (error_buf, fmt, args); | 227 | vsnprintf (error_buf, sizeof(error_buf), fmt, args); |
228 | va_end (args); | 228 | va_end (args); |
229 | switch (UFS_SB(sb)->s_mount_opt & UFS_MOUNT_ONERROR) { | 229 | switch (UFS_SB(sb)->s_mount_opt & UFS_MOUNT_ONERROR) { |
230 | case UFS_MOUNT_ONERROR_PANIC: | 230 | case UFS_MOUNT_ONERROR_PANIC: |
@@ -255,7 +255,7 @@ void ufs_panic (struct super_block * sb, const char * function, | |||
255 | sb->s_dirt = 1; | 255 | sb->s_dirt = 1; |
256 | } | 256 | } |
257 | va_start (args, fmt); | 257 | va_start (args, fmt); |
258 | vsprintf (error_buf, fmt, args); | 258 | vsnprintf (error_buf, sizeof(error_buf), fmt, args); |
259 | va_end (args); | 259 | va_end (args); |
260 | sb->s_flags |= MS_RDONLY; | 260 | sb->s_flags |= MS_RDONLY; |
261 | printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n", | 261 | printk (KERN_CRIT "UFS-fs panic (device %s): %s: %s\n", |
@@ -268,7 +268,7 @@ void ufs_warning (struct super_block * sb, const char * function, | |||
268 | va_list args; | 268 | va_list args; |
269 | 269 | ||
270 | va_start (args, fmt); | 270 | va_start (args, fmt); |
271 | vsprintf (error_buf, fmt, args); | 271 | vsnprintf (error_buf, sizeof(error_buf), fmt, args); |
272 | va_end (args); | 272 | va_end (args); |
273 | printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n", | 273 | printk (KERN_WARNING "UFS-fs warning (device %s): %s: %s\n", |
274 | sb->s_id, function, error_buf); | 274 | sb->s_id, function, error_buf); |
@@ -1204,12 +1204,12 @@ static int ufs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1204 | return 0; | 1204 | return 0; |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | static kmem_cache_t * ufs_inode_cachep; | 1207 | static struct kmem_cache * ufs_inode_cachep; |
1208 | 1208 | ||
1209 | static struct inode *ufs_alloc_inode(struct super_block *sb) | 1209 | static struct inode *ufs_alloc_inode(struct super_block *sb) |
1210 | { | 1210 | { |
1211 | struct ufs_inode_info *ei; | 1211 | struct ufs_inode_info *ei; |
1212 | ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, SLAB_KERNEL); | 1212 | ei = (struct ufs_inode_info *)kmem_cache_alloc(ufs_inode_cachep, GFP_KERNEL); |
1213 | if (!ei) | 1213 | if (!ei) |
1214 | return NULL; | 1214 | return NULL; |
1215 | ei->vfs_inode.i_version = 1; | 1215 | ei->vfs_inode.i_version = 1; |
@@ -1221,7 +1221,7 @@ static void ufs_destroy_inode(struct inode *inode) | |||
1221 | kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); | 1221 | kmem_cache_free(ufs_inode_cachep, UFS_I(inode)); |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | 1224 | static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) |
1225 | { | 1225 | { |
1226 | struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; | 1226 | struct ufs_inode_info *ei = (struct ufs_inode_info *) foo; |
1227 | 1227 | ||
diff --git a/fs/ufs/util.h b/fs/ufs/util.h index 28fce6c239b5..7dd12bb1d62b 100644 --- a/fs/ufs/util.h +++ b/fs/ufs/util.h | |||
@@ -299,7 +299,7 @@ static inline void *get_usb_offset(struct ufs_sb_private_info *uspi, | |||
299 | 299 | ||
300 | #define ubh_get_addr16(ubh,begin) \ | 300 | #define ubh_get_addr16(ubh,begin) \ |
301 | (((__fs16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \ | 301 | (((__fs16*)((ubh)->bh[(begin) >> (uspi->s_fshift-1)]->b_data)) + \ |
302 | ((begin) & (uspi->fsize>>1) - 1))) | 302 | ((begin) & ((uspi->fsize>>1) - 1))) |
303 | 303 | ||
304 | #define ubh_get_addr32(ubh,begin) \ | 304 | #define ubh_get_addr32(ubh,begin) \ |
305 | (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ | 305 | (((__fs32*)((ubh)->bh[(begin) >> (uspi->s_fshift-2)]->b_data)) + \ |
diff --git a/fs/utimes.c b/fs/utimes.c index 1bcd852fc4a9..99cf2cb11fec 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <linux/fs.h> | 2 | #include <linux/fs.h> |
3 | #include <linux/linkage.h> | 3 | #include <linux/linkage.h> |
4 | #include <linux/namei.h> | 4 | #include <linux/namei.h> |
5 | #include <linux/sched.h> | ||
5 | #include <linux/utime.h> | 6 | #include <linux/utime.h> |
6 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
7 | #include <asm/unistd.h> | 8 | #include <asm/unistd.h> |
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c index edb711ff7b05..0afd745a37cd 100644 --- a/fs/vfat/namei.c +++ b/fs/vfat/namei.c | |||
@@ -1004,6 +1004,7 @@ static struct inode_operations vfat_dir_inode_operations = { | |||
1004 | .rmdir = vfat_rmdir, | 1004 | .rmdir = vfat_rmdir, |
1005 | .rename = vfat_rename, | 1005 | .rename = vfat_rename, |
1006 | .setattr = fat_notify_change, | 1006 | .setattr = fat_notify_change, |
1007 | .getattr = fat_getattr, | ||
1007 | }; | 1008 | }; |
1008 | 1009 | ||
1009 | static int vfat_fill_super(struct super_block *sb, void *data, int silent) | 1010 | static int vfat_fill_super(struct super_block *sb, void *data, int silent) |
diff --git a/fs/xfs/Makefile-linux-2.6 b/fs/xfs/Makefile-linux-2.6 index 291948d5085a..b49989bb89ad 100644 --- a/fs/xfs/Makefile-linux-2.6 +++ b/fs/xfs/Makefile-linux-2.6 | |||
@@ -21,22 +21,7 @@ EXTRA_CFLAGS += -Ifs/xfs -Ifs/xfs/linux-2.6 -funsigned-char | |||
21 | XFS_LINUX := linux-2.6 | 21 | XFS_LINUX := linux-2.6 |
22 | 22 | ||
23 | ifeq ($(CONFIG_XFS_DEBUG),y) | 23 | ifeq ($(CONFIG_XFS_DEBUG),y) |
24 | EXTRA_CFLAGS += -g -DSTATIC="" -DDEBUG | 24 | EXTRA_CFLAGS += -g |
25 | EXTRA_CFLAGS += -DXFS_BUF_LOCK_TRACKING | ||
26 | endif | ||
27 | ifeq ($(CONFIG_XFS_TRACE),y) | ||
28 | EXTRA_CFLAGS += -DXFS_ALLOC_TRACE | ||
29 | EXTRA_CFLAGS += -DXFS_ATTR_TRACE | ||
30 | EXTRA_CFLAGS += -DXFS_BLI_TRACE | ||
31 | EXTRA_CFLAGS += -DXFS_BMAP_TRACE | ||
32 | EXTRA_CFLAGS += -DXFS_BMBT_TRACE | ||
33 | EXTRA_CFLAGS += -DXFS_DIR2_TRACE | ||
34 | EXTRA_CFLAGS += -DXFS_DQUOT_TRACE | ||
35 | EXTRA_CFLAGS += -DXFS_ILOCK_TRACE | ||
36 | EXTRA_CFLAGS += -DXFS_LOG_TRACE | ||
37 | EXTRA_CFLAGS += -DXFS_RW_TRACE | ||
38 | EXTRA_CFLAGS += -DXFS_BUF_TRACE | ||
39 | EXTRA_CFLAGS += -DXFS_VNODE_TRACE | ||
40 | endif | 25 | endif |
41 | 26 | ||
42 | obj-$(CONFIG_XFS_FS) += xfs.o | 27 | obj-$(CONFIG_XFS_FS) += xfs.o |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 09360cf1e1f2..8e6b56fc1cad 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -149,9 +149,10 @@ xfs_destroy_ioend( | |||
149 | */ | 149 | */ |
150 | STATIC void | 150 | STATIC void |
151 | xfs_end_bio_delalloc( | 151 | xfs_end_bio_delalloc( |
152 | void *data) | 152 | struct work_struct *work) |
153 | { | 153 | { |
154 | xfs_ioend_t *ioend = data; | 154 | xfs_ioend_t *ioend = |
155 | container_of(work, xfs_ioend_t, io_work); | ||
155 | 156 | ||
156 | xfs_destroy_ioend(ioend); | 157 | xfs_destroy_ioend(ioend); |
157 | } | 158 | } |
@@ -161,9 +162,10 @@ xfs_end_bio_delalloc( | |||
161 | */ | 162 | */ |
162 | STATIC void | 163 | STATIC void |
163 | xfs_end_bio_written( | 164 | xfs_end_bio_written( |
164 | void *data) | 165 | struct work_struct *work) |
165 | { | 166 | { |
166 | xfs_ioend_t *ioend = data; | 167 | xfs_ioend_t *ioend = |
168 | container_of(work, xfs_ioend_t, io_work); | ||
167 | 169 | ||
168 | xfs_destroy_ioend(ioend); | 170 | xfs_destroy_ioend(ioend); |
169 | } | 171 | } |
@@ -176,9 +178,10 @@ xfs_end_bio_written( | |||
176 | */ | 178 | */ |
177 | STATIC void | 179 | STATIC void |
178 | xfs_end_bio_unwritten( | 180 | xfs_end_bio_unwritten( |
179 | void *data) | 181 | struct work_struct *work) |
180 | { | 182 | { |
181 | xfs_ioend_t *ioend = data; | 183 | xfs_ioend_t *ioend = |
184 | container_of(work, xfs_ioend_t, io_work); | ||
182 | bhv_vnode_t *vp = ioend->io_vnode; | 185 | bhv_vnode_t *vp = ioend->io_vnode; |
183 | xfs_off_t offset = ioend->io_offset; | 186 | xfs_off_t offset = ioend->io_offset; |
184 | size_t size = ioend->io_size; | 187 | size_t size = ioend->io_size; |
@@ -220,11 +223,11 @@ xfs_alloc_ioend( | |||
220 | ioend->io_size = 0; | 223 | ioend->io_size = 0; |
221 | 224 | ||
222 | if (type == IOMAP_UNWRITTEN) | 225 | if (type == IOMAP_UNWRITTEN) |
223 | INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten, ioend); | 226 | INIT_WORK(&ioend->io_work, xfs_end_bio_unwritten); |
224 | else if (type == IOMAP_DELAY) | 227 | else if (type == IOMAP_DELAY) |
225 | INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc, ioend); | 228 | INIT_WORK(&ioend->io_work, xfs_end_bio_delalloc); |
226 | else | 229 | else |
227 | INIT_WORK(&ioend->io_work, xfs_end_bio_written, ioend); | 230 | INIT_WORK(&ioend->io_work, xfs_end_bio_written); |
228 | 231 | ||
229 | return ioend; | 232 | return ioend; |
230 | } | 233 | } |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index db5f5a3608ca..4fb01ffdfd1a 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #include "xfs.h" | ||
18 | #include <linux/stddef.h> | 19 | #include <linux/stddef.h> |
19 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
@@ -31,7 +32,7 @@ | |||
31 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
32 | #include <linux/migrate.h> | 33 | #include <linux/migrate.h> |
33 | #include <linux/backing-dev.h> | 34 | #include <linux/backing-dev.h> |
34 | #include "xfs_linux.h" | 35 | #include <linux/freezer.h> |
35 | 36 | ||
36 | STATIC kmem_zone_t *xfs_buf_zone; | 37 | STATIC kmem_zone_t *xfs_buf_zone; |
37 | STATIC kmem_shaker_t xfs_buf_shake; | 38 | STATIC kmem_shaker_t xfs_buf_shake; |
@@ -994,9 +995,10 @@ xfs_buf_wait_unpin( | |||
994 | 995 | ||
995 | STATIC void | 996 | STATIC void |
996 | xfs_buf_iodone_work( | 997 | xfs_buf_iodone_work( |
997 | void *v) | 998 | struct work_struct *work) |
998 | { | 999 | { |
999 | xfs_buf_t *bp = (xfs_buf_t *)v; | 1000 | xfs_buf_t *bp = |
1001 | container_of(work, xfs_buf_t, b_iodone_work); | ||
1000 | 1002 | ||
1001 | if (bp->b_iodone) | 1003 | if (bp->b_iodone) |
1002 | (*(bp->b_iodone))(bp); | 1004 | (*(bp->b_iodone))(bp); |
@@ -1017,10 +1019,10 @@ xfs_buf_ioend( | |||
1017 | 1019 | ||
1018 | if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) { | 1020 | if ((bp->b_iodone) || (bp->b_flags & XBF_ASYNC)) { |
1019 | if (schedule) { | 1021 | if (schedule) { |
1020 | INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work, bp); | 1022 | INIT_WORK(&bp->b_iodone_work, xfs_buf_iodone_work); |
1021 | queue_work(xfslogd_workqueue, &bp->b_iodone_work); | 1023 | queue_work(xfslogd_workqueue, &bp->b_iodone_work); |
1022 | } else { | 1024 | } else { |
1023 | xfs_buf_iodone_work(bp); | 1025 | xfs_buf_iodone_work(&bp->b_iodone_work); |
1024 | } | 1026 | } |
1025 | } else { | 1027 | } else { |
1026 | up(&bp->b_iodonesema); | 1028 | up(&bp->b_iodonesema); |
@@ -1406,7 +1408,7 @@ xfs_alloc_bufhash( | |||
1406 | btp->bt_hashshift = external ? 3 : 8; /* 8 or 256 buckets */ | 1408 | btp->bt_hashshift = external ? 3 : 8; /* 8 or 256 buckets */ |
1407 | btp->bt_hashmask = (1 << btp->bt_hashshift) - 1; | 1409 | btp->bt_hashmask = (1 << btp->bt_hashshift) - 1; |
1408 | btp->bt_hash = kmem_zalloc((1 << btp->bt_hashshift) * | 1410 | btp->bt_hash = kmem_zalloc((1 << btp->bt_hashshift) * |
1409 | sizeof(xfs_bufhash_t), KM_SLEEP); | 1411 | sizeof(xfs_bufhash_t), KM_SLEEP | KM_LARGE); |
1410 | for (i = 0; i < (1 << btp->bt_hashshift); i++) { | 1412 | for (i = 0; i < (1 << btp->bt_hashshift); i++) { |
1411 | spin_lock_init(&btp->bt_hash[i].bh_lock); | 1413 | spin_lock_init(&btp->bt_hash[i].bh_lock); |
1412 | INIT_LIST_HEAD(&btp->bt_hash[i].bh_list); | 1414 | INIT_LIST_HEAD(&btp->bt_hash[i].bh_list); |
@@ -1825,11 +1827,11 @@ xfs_buf_init(void) | |||
1825 | if (!xfs_buf_zone) | 1827 | if (!xfs_buf_zone) |
1826 | goto out_free_trace_buf; | 1828 | goto out_free_trace_buf; |
1827 | 1829 | ||
1828 | xfslogd_workqueue = create_workqueue("xfslogd"); | 1830 | xfslogd_workqueue = create_freezeable_workqueue("xfslogd"); |
1829 | if (!xfslogd_workqueue) | 1831 | if (!xfslogd_workqueue) |
1830 | goto out_free_buf_zone; | 1832 | goto out_free_buf_zone; |
1831 | 1833 | ||
1832 | xfsdatad_workqueue = create_workqueue("xfsdatad"); | 1834 | xfsdatad_workqueue = create_freezeable_workqueue("xfsdatad"); |
1833 | if (!xfsdatad_workqueue) | 1835 | if (!xfsdatad_workqueue) |
1834 | goto out_destroy_xfslogd_workqueue; | 1836 | goto out_destroy_xfslogd_workqueue; |
1835 | 1837 | ||
diff --git a/fs/xfs/linux-2.6/xfs_dmapi_priv.h b/fs/xfs/linux-2.6/xfs_dmapi_priv.h new file mode 100644 index 000000000000..a8b0b1685eed --- /dev/null +++ b/fs/xfs/linux-2.6/xfs_dmapi_priv.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_DMAPI_PRIV_H__ | ||
19 | #define __XFS_DMAPI_PRIV_H__ | ||
20 | |||
21 | /* | ||
22 | * Based on IO_ISDIRECT, decide which i_ flag is set. | ||
23 | */ | ||
24 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ | ||
25 | DM_FLAGS_IMUX : 0) | ||
26 | #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) | ||
27 | |||
28 | #endif /*__XFS_DMAPI_PRIV_H__*/ | ||
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index a74f854d91e6..74d094829a4d 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -341,8 +341,11 @@ xfs_open_by_handle( | |||
341 | put_unused_fd(new_fd); | 341 | put_unused_fd(new_fd); |
342 | return -XFS_ERROR(-PTR_ERR(filp)); | 342 | return -XFS_ERROR(-PTR_ERR(filp)); |
343 | } | 343 | } |
344 | if (inode->i_mode & S_IFREG) | 344 | if (inode->i_mode & S_IFREG) { |
345 | /* invisible operation should not change atime */ | ||
346 | filp->f_flags |= O_NOATIME; | ||
345 | filp->f_op = &xfs_invis_file_operations; | 347 | filp->f_op = &xfs_invis_file_operations; |
348 | } | ||
346 | 349 | ||
347 | fd_install(new_fd, filp); | 350 | fd_install(new_fd, filp); |
348 | return new_fd; | 351 | return new_fd; |
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 38c4d128a8c0..b93265b7c79c 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/mempool.h> | 56 | #include <linux/mempool.h> |
57 | #include <linux/writeback.h> | 57 | #include <linux/writeback.h> |
58 | #include <linux/kthread.h> | 58 | #include <linux/kthread.h> |
59 | #include <linux/freezer.h> | ||
59 | 60 | ||
60 | STATIC struct quotactl_ops xfs_quotactl_operations; | 61 | STATIC struct quotactl_ops xfs_quotactl_operations; |
61 | STATIC struct super_operations xfs_super_operations; | 62 | STATIC struct super_operations xfs_super_operations; |
@@ -227,9 +228,7 @@ xfs_initialize_vnode( | |||
227 | xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip); | 228 | xfs_revalidate_inode(XFS_BHVTOM(bdp), vp, ip); |
228 | xfs_set_inodeops(inode); | 229 | xfs_set_inodeops(inode); |
229 | 230 | ||
230 | spin_lock(&ip->i_flags_lock); | 231 | xfs_iflags_clear(ip, XFS_INEW); |
231 | ip->i_flags &= ~XFS_INEW; | ||
232 | spin_unlock(&ip->i_flags_lock); | ||
233 | barrier(); | 232 | barrier(); |
234 | 233 | ||
235 | unlock_new_inode(inode); | 234 | unlock_new_inode(inode); |
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c index c75f68361e33..4363512d2f90 100644 --- a/fs/xfs/support/debug.c +++ b/fs/xfs/support/debug.c | |||
@@ -15,11 +15,9 @@ | |||
15 | * along with this program; if not, write the Free Software Foundation, | 15 | * along with this program; if not, write the Free Software Foundation, |
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ | 17 | */ |
18 | #include <xfs.h> | ||
18 | #include "debug.h" | 19 | #include "debug.h" |
19 | #include "spin.h" | 20 | #include "spin.h" |
20 | #include <asm/page.h> | ||
21 | #include <linux/sched.h> | ||
22 | #include <linux/kernel.h> | ||
23 | 21 | ||
24 | static char message[256]; /* keep it off the stack */ | 22 | static char message[256]; /* keep it off the stack */ |
25 | static DEFINE_SPINLOCK(xfs_err_lock); | 23 | static DEFINE_SPINLOCK(xfs_err_lock); |
diff --git a/fs/xfs/support/move.c b/fs/xfs/support/move.c index caefa17b80fe..ac8617ca3909 100644 --- a/fs/xfs/support/move.c +++ b/fs/xfs/support/move.c | |||
@@ -22,7 +22,7 @@ | |||
22 | * as we go. | 22 | * as we go. |
23 | */ | 23 | */ |
24 | int | 24 | int |
25 | uio_read(caddr_t src, size_t len, struct uio *uio) | 25 | xfs_uio_read(caddr_t src, size_t len, struct uio *uio) |
26 | { | 26 | { |
27 | size_t count; | 27 | size_t count; |
28 | 28 | ||
diff --git a/fs/xfs/support/move.h b/fs/xfs/support/move.h index 97a2498d2da3..977879c24ff5 100644 --- a/fs/xfs/support/move.h +++ b/fs/xfs/support/move.h | |||
@@ -65,6 +65,6 @@ struct uio { | |||
65 | typedef struct uio uio_t; | 65 | typedef struct uio uio_t; |
66 | typedef struct iovec iovec_t; | 66 | typedef struct iovec iovec_t; |
67 | 67 | ||
68 | extern int uio_read (caddr_t, size_t, uio_t *); | 68 | extern int xfs_uio_read (caddr_t, size_t, uio_t *); |
69 | 69 | ||
70 | #endif /* __XFS_SUPPORT_MOVE_H__ */ | 70 | #endif /* __XFS_SUPPORT_MOVE_H__ */ |
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h index 1a48dbb902a7..bf0a12040b13 100644 --- a/fs/xfs/xfs.h +++ b/fs/xfs/xfs.h | |||
@@ -17,5 +17,28 @@ | |||
17 | */ | 17 | */ |
18 | #ifndef __XFS_H__ | 18 | #ifndef __XFS_H__ |
19 | #define __XFS_H__ | 19 | #define __XFS_H__ |
20 | |||
21 | #ifdef CONFIG_XFS_DEBUG | ||
22 | #define STATIC | ||
23 | #define DEBUG 1 | ||
24 | #define XFS_BUF_LOCK_TRACKING 1 | ||
25 | /* #define QUOTADEBUG 1 */ | ||
26 | #endif | ||
27 | |||
28 | #ifdef CONFIG_XFS_TRACE | ||
29 | #define XFS_ALLOC_TRACE 1 | ||
30 | #define XFS_ATTR_TRACE 1 | ||
31 | #define XFS_BLI_TRACE 1 | ||
32 | #define XFS_BMAP_TRACE 1 | ||
33 | #define XFS_BMBT_TRACE 1 | ||
34 | #define XFS_DIR2_TRACE 1 | ||
35 | #define XFS_DQUOT_TRACE 1 | ||
36 | #define XFS_ILOCK_TRACE 1 | ||
37 | #define XFS_LOG_TRACE 1 | ||
38 | #define XFS_RW_TRACE 1 | ||
39 | #define XFS_BUF_TRACE 1 | ||
40 | #define XFS_VNODE_TRACE 1 | ||
41 | #endif | ||
42 | |||
20 | #include <linux-2.6/xfs_linux.h> | 43 | #include <linux-2.6/xfs_linux.h> |
21 | #endif /* __XFS_H__ */ | 44 | #endif /* __XFS_H__ */ |
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 5b050c06795f..498ad50d1f45 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c | |||
@@ -1171,6 +1171,8 @@ xfs_bmap_add_extent_delay_real( | |||
1171 | xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); | 1171 | xfs_bmap_trace_pre_update(fname, "0", ip, idx, XFS_DATA_FORK); |
1172 | xfs_bmbt_set_blockcount(ep, temp); | 1172 | xfs_bmbt_set_blockcount(ep, temp); |
1173 | r[0] = *new; | 1173 | r[0] = *new; |
1174 | r[1].br_state = PREV.br_state; | ||
1175 | r[1].br_startblock = 0; | ||
1174 | r[1].br_startoff = new_endoff; | 1176 | r[1].br_startoff = new_endoff; |
1175 | temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; | 1177 | temp2 = PREV.br_startoff + PREV.br_blockcount - new_endoff; |
1176 | r[1].br_blockcount = temp2; | 1178 | r[1].br_blockcount = temp2; |
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 8edbe1adb95b..8e8e5279334a 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c | |||
@@ -678,7 +678,7 @@ xfs_dir2_put_dirent64_uio( | |||
678 | idbp->d_off = pa->cook; | 678 | idbp->d_off = pa->cook; |
679 | idbp->d_name[namelen] = '\0'; | 679 | idbp->d_name[namelen] = '\0'; |
680 | memcpy(idbp->d_name, pa->name, namelen); | 680 | memcpy(idbp->d_name, pa->name, namelen); |
681 | rval = uio_read((caddr_t)idbp, reclen, uio); | 681 | rval = xfs_uio_read((caddr_t)idbp, reclen, uio); |
682 | pa->done = (rval == 0); | 682 | pa->done = (rval == 0); |
683 | return rval; | 683 | return rval; |
684 | } | 684 | } |
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h index 4e7865ad6f0e..adc3d251240d 100644 --- a/fs/xfs/xfs_dmapi.h +++ b/fs/xfs/xfs_dmapi.h | |||
@@ -157,27 +157,9 @@ typedef enum { | |||
157 | #define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */ | 157 | #define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */ |
158 | 158 | ||
159 | /* | 159 | /* |
160 | * Based on IO_ISDIRECT, decide which i_ flag is set. | 160 | * Pull in platform specific event flags defines |
161 | */ | 161 | */ |
162 | #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) | 162 | #include "xfs_dmapi_priv.h" |
163 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ | ||
164 | DM_FLAGS_IMUX : 0) | ||
165 | #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) | ||
166 | #endif | ||
167 | |||
168 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) && \ | ||
169 | (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)) | ||
170 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ | ||
171 | DM_FLAGS_IALLOCSEM_RD : DM_FLAGS_IMUX) | ||
172 | #define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX) | ||
173 | #endif | ||
174 | |||
175 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21) | ||
176 | #define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \ | ||
177 | 0 : DM_FLAGS_IMUX) | ||
178 | #define DM_SEM_FLAG_WR (DM_FLAGS_IMUX) | ||
179 | #endif | ||
180 | |||
181 | 163 | ||
182 | /* | 164 | /* |
183 | * Macros to turn caller specified delay/block flags into | 165 | * Macros to turn caller specified delay/block flags into |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index b73d216ecaf9..c1c89dac19cc 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -215,7 +215,7 @@ again: | |||
215 | * If INEW is set this inode is being set up | 215 | * If INEW is set this inode is being set up |
216 | * we need to pause and try again. | 216 | * we need to pause and try again. |
217 | */ | 217 | */ |
218 | if (ip->i_flags & XFS_INEW) { | 218 | if (xfs_iflags_test(ip, XFS_INEW)) { |
219 | read_unlock(&ih->ih_lock); | 219 | read_unlock(&ih->ih_lock); |
220 | delay(1); | 220 | delay(1); |
221 | XFS_STATS_INC(xs_ig_frecycle); | 221 | XFS_STATS_INC(xs_ig_frecycle); |
@@ -230,22 +230,50 @@ again: | |||
230 | * on its way out of the system, | 230 | * on its way out of the system, |
231 | * we need to pause and try again. | 231 | * we need to pause and try again. |
232 | */ | 232 | */ |
233 | if (ip->i_flags & XFS_IRECLAIM) { | 233 | if (xfs_iflags_test(ip, XFS_IRECLAIM)) { |
234 | read_unlock(&ih->ih_lock); | 234 | read_unlock(&ih->ih_lock); |
235 | delay(1); | 235 | delay(1); |
236 | XFS_STATS_INC(xs_ig_frecycle); | 236 | XFS_STATS_INC(xs_ig_frecycle); |
237 | 237 | ||
238 | goto again; | 238 | goto again; |
239 | } | 239 | } |
240 | ASSERT(xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | ||
241 | |||
242 | /* | ||
243 | * If lookup is racing with unlink, then we | ||
244 | * should return an error immediately so we | ||
245 | * don't remove it from the reclaim list and | ||
246 | * potentially leak the inode. | ||
247 | */ | ||
248 | if ((ip->i_d.di_mode == 0) && | ||
249 | !(flags & XFS_IGET_CREATE)) { | ||
250 | read_unlock(&ih->ih_lock); | ||
251 | return ENOENT; | ||
252 | } | ||
253 | |||
254 | /* | ||
255 | * There may be transactions sitting in the | ||
256 | * incore log buffers or being flushed to disk | ||
257 | * at this time. We can't clear the | ||
258 | * XFS_IRECLAIMABLE flag until these | ||
259 | * transactions have hit the disk, otherwise we | ||
260 | * will void the guarantee the flag provides | ||
261 | * xfs_iunpin() | ||
262 | */ | ||
263 | if (xfs_ipincount(ip)) { | ||
264 | read_unlock(&ih->ih_lock); | ||
265 | xfs_log_force(mp, 0, | ||
266 | XFS_LOG_FORCE|XFS_LOG_SYNC); | ||
267 | XFS_STATS_INC(xs_ig_frecycle); | ||
268 | goto again; | ||
269 | } | ||
240 | 270 | ||
241 | vn_trace_exit(vp, "xfs_iget.alloc", | 271 | vn_trace_exit(vp, "xfs_iget.alloc", |
242 | (inst_t *)__return_address); | 272 | (inst_t *)__return_address); |
243 | 273 | ||
244 | XFS_STATS_INC(xs_ig_found); | 274 | XFS_STATS_INC(xs_ig_found); |
245 | 275 | ||
246 | spin_lock(&ip->i_flags_lock); | 276 | xfs_iflags_clear(ip, XFS_IRECLAIMABLE); |
247 | ip->i_flags &= ~XFS_IRECLAIMABLE; | ||
248 | spin_unlock(&ip->i_flags_lock); | ||
249 | version = ih->ih_version; | 277 | version = ih->ih_version; |
250 | read_unlock(&ih->ih_lock); | 278 | read_unlock(&ih->ih_lock); |
251 | xfs_ihash_promote(ih, ip, version); | 279 | xfs_ihash_promote(ih, ip, version); |
@@ -299,10 +327,7 @@ finish_inode: | |||
299 | if (lock_flags != 0) | 327 | if (lock_flags != 0) |
300 | xfs_ilock(ip, lock_flags); | 328 | xfs_ilock(ip, lock_flags); |
301 | 329 | ||
302 | spin_lock(&ip->i_flags_lock); | 330 | xfs_iflags_clear(ip, XFS_ISTALE); |
303 | ip->i_flags &= ~XFS_ISTALE; | ||
304 | spin_unlock(&ip->i_flags_lock); | ||
305 | |||
306 | vn_trace_exit(vp, "xfs_iget.found", | 331 | vn_trace_exit(vp, "xfs_iget.found", |
307 | (inst_t *)__return_address); | 332 | (inst_t *)__return_address); |
308 | goto return_ip; | 333 | goto return_ip; |
@@ -371,10 +396,7 @@ finish_inode: | |||
371 | ih->ih_next = ip; | 396 | ih->ih_next = ip; |
372 | ip->i_udquot = ip->i_gdquot = NULL; | 397 | ip->i_udquot = ip->i_gdquot = NULL; |
373 | ih->ih_version++; | 398 | ih->ih_version++; |
374 | spin_lock(&ip->i_flags_lock); | 399 | xfs_iflags_set(ip, XFS_INEW); |
375 | ip->i_flags |= XFS_INEW; | ||
376 | spin_unlock(&ip->i_flags_lock); | ||
377 | |||
378 | write_unlock(&ih->ih_lock); | 400 | write_unlock(&ih->ih_lock); |
379 | 401 | ||
380 | /* | 402 | /* |
@@ -625,7 +647,7 @@ xfs_iput_new(xfs_inode_t *ip, | |||
625 | vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); | 647 | vn_trace_entry(vp, "xfs_iput_new", (inst_t *)__return_address); |
626 | 648 | ||
627 | if ((ip->i_d.di_mode == 0)) { | 649 | if ((ip->i_d.di_mode == 0)) { |
628 | ASSERT(!(ip->i_flags & XFS_IRECLAIMABLE)); | 650 | ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); |
629 | vn_mark_bad(vp); | 651 | vn_mark_bad(vp); |
630 | } | 652 | } |
631 | if (inode->i_state & I_NEW) | 653 | if (inode->i_state & I_NEW) |
@@ -683,6 +705,7 @@ xfs_ireclaim(xfs_inode_t *ip) | |||
683 | /* | 705 | /* |
684 | * Free all memory associated with the inode. | 706 | * Free all memory associated with the inode. |
685 | */ | 707 | */ |
708 | xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
686 | xfs_idestroy(ip); | 709 | xfs_idestroy(ip); |
687 | } | 710 | } |
688 | 711 | ||
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index c27d7d495aa0..44dfac521285 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -2193,7 +2193,7 @@ xfs_ifree_cluster( | |||
2193 | /* Inode not in memory or we found it already, | 2193 | /* Inode not in memory or we found it already, |
2194 | * nothing to do | 2194 | * nothing to do |
2195 | */ | 2195 | */ |
2196 | if (!ip || (ip->i_flags & XFS_ISTALE)) { | 2196 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { |
2197 | read_unlock(&ih->ih_lock); | 2197 | read_unlock(&ih->ih_lock); |
2198 | continue; | 2198 | continue; |
2199 | } | 2199 | } |
@@ -2215,10 +2215,7 @@ xfs_ifree_cluster( | |||
2215 | 2215 | ||
2216 | if (ip == free_ip) { | 2216 | if (ip == free_ip) { |
2217 | if (xfs_iflock_nowait(ip)) { | 2217 | if (xfs_iflock_nowait(ip)) { |
2218 | spin_lock(&ip->i_flags_lock); | 2218 | xfs_iflags_set(ip, XFS_ISTALE); |
2219 | ip->i_flags |= XFS_ISTALE; | ||
2220 | spin_unlock(&ip->i_flags_lock); | ||
2221 | |||
2222 | if (xfs_inode_clean(ip)) { | 2219 | if (xfs_inode_clean(ip)) { |
2223 | xfs_ifunlock(ip); | 2220 | xfs_ifunlock(ip); |
2224 | } else { | 2221 | } else { |
@@ -2231,9 +2228,7 @@ xfs_ifree_cluster( | |||
2231 | 2228 | ||
2232 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { | 2229 | if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { |
2233 | if (xfs_iflock_nowait(ip)) { | 2230 | if (xfs_iflock_nowait(ip)) { |
2234 | spin_lock(&ip->i_flags_lock); | 2231 | xfs_iflags_set(ip, XFS_ISTALE); |
2235 | ip->i_flags |= XFS_ISTALE; | ||
2236 | spin_unlock(&ip->i_flags_lock); | ||
2237 | 2232 | ||
2238 | if (xfs_inode_clean(ip)) { | 2233 | if (xfs_inode_clean(ip)) { |
2239 | xfs_ifunlock(ip); | 2234 | xfs_ifunlock(ip); |
@@ -2263,9 +2258,7 @@ xfs_ifree_cluster( | |||
2263 | AIL_LOCK(mp,s); | 2258 | AIL_LOCK(mp,s); |
2264 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 2259 | iip->ili_flush_lsn = iip->ili_item.li_lsn; |
2265 | AIL_UNLOCK(mp, s); | 2260 | AIL_UNLOCK(mp, s); |
2266 | spin_lock(&iip->ili_inode->i_flags_lock); | 2261 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); |
2267 | iip->ili_inode->i_flags |= XFS_ISTALE; | ||
2268 | spin_unlock(&iip->ili_inode->i_flags_lock); | ||
2269 | pre_flushed++; | 2262 | pre_flushed++; |
2270 | } | 2263 | } |
2271 | lip = lip->li_bio_list; | 2264 | lip = lip->li_bio_list; |
@@ -2748,42 +2741,39 @@ xfs_iunpin( | |||
2748 | { | 2741 | { |
2749 | ASSERT(atomic_read(&ip->i_pincount) > 0); | 2742 | ASSERT(atomic_read(&ip->i_pincount) > 0); |
2750 | 2743 | ||
2751 | if (atomic_dec_and_test(&ip->i_pincount)) { | 2744 | if (atomic_dec_and_lock(&ip->i_pincount, &ip->i_flags_lock)) { |
2745 | |||
2752 | /* | 2746 | /* |
2753 | * If the inode is currently being reclaimed, the | 2747 | * If the inode is currently being reclaimed, the link between |
2754 | * linux inode _and_ the xfs vnode may have been | 2748 | * the bhv_vnode and the xfs_inode will be broken after the |
2755 | * freed so we cannot reference either of them safely. | 2749 | * XFS_IRECLAIM* flag is set. Hence, if these flags are not |
2756 | * Hence we should not try to do anything to them | 2750 | * set, then we can move forward and mark the linux inode dirty |
2757 | * if the xfs inode is currently in the reclaim | 2751 | * knowing that it is still valid as it won't freed until after |
2758 | * path. | 2752 | * the bhv_vnode<->xfs_inode link is broken in xfs_reclaim. The |
2753 | * i_flags_lock is used to synchronise the setting of the | ||
2754 | * XFS_IRECLAIM* flags and the breaking of the link, and so we | ||
2755 | * can execute atomically w.r.t to reclaim by holding this lock | ||
2756 | * here. | ||
2759 | * | 2757 | * |
2760 | * However, we still need to issue the unpin wakeup | 2758 | * However, we still need to issue the unpin wakeup call as the |
2761 | * call as the inode reclaim may be blocked waiting for | 2759 | * inode reclaim may be blocked waiting for the inode to become |
2762 | * the inode to become unpinned. | 2760 | * unpinned. |
2763 | */ | 2761 | */ |
2764 | struct inode *inode = NULL; | ||
2765 | 2762 | ||
2766 | spin_lock(&ip->i_flags_lock); | 2763 | if (!__xfs_iflags_test(ip, XFS_IRECLAIM|XFS_IRECLAIMABLE)) { |
2767 | if (!(ip->i_flags & (XFS_IRECLAIM|XFS_IRECLAIMABLE))) { | ||
2768 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); | 2764 | bhv_vnode_t *vp = XFS_ITOV_NULL(ip); |
2765 | struct inode *inode = NULL; | ||
2766 | |||
2767 | BUG_ON(vp == NULL); | ||
2768 | inode = vn_to_inode(vp); | ||
2769 | BUG_ON(inode->i_state & I_CLEAR); | ||
2769 | 2770 | ||
2770 | /* make sync come back and flush this inode */ | 2771 | /* make sync come back and flush this inode */ |
2771 | if (vp) { | 2772 | if (!(inode->i_state & (I_NEW|I_FREEING))) |
2772 | inode = vn_to_inode(vp); | 2773 | mark_inode_dirty_sync(inode); |
2773 | |||
2774 | if (!(inode->i_state & | ||
2775 | (I_NEW|I_FREEING|I_CLEAR))) { | ||
2776 | inode = igrab(inode); | ||
2777 | if (inode) | ||
2778 | mark_inode_dirty_sync(inode); | ||
2779 | } else | ||
2780 | inode = NULL; | ||
2781 | } | ||
2782 | } | 2774 | } |
2783 | spin_unlock(&ip->i_flags_lock); | 2775 | spin_unlock(&ip->i_flags_lock); |
2784 | wake_up(&ip->i_ipin_wait); | 2776 | wake_up(&ip->i_ipin_wait); |
2785 | if (inode) | ||
2786 | iput(inode); | ||
2787 | } | 2777 | } |
2788 | } | 2778 | } |
2789 | 2779 | ||
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index e96eb0835fe6..bc823720d88f 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -305,6 +305,47 @@ typedef struct xfs_inode { | |||
305 | #endif | 305 | #endif |
306 | } xfs_inode_t; | 306 | } xfs_inode_t; |
307 | 307 | ||
308 | |||
309 | /* | ||
310 | * i_flags helper functions | ||
311 | */ | ||
312 | static inline void | ||
313 | __xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) | ||
314 | { | ||
315 | ip->i_flags |= flags; | ||
316 | } | ||
317 | |||
318 | static inline void | ||
319 | xfs_iflags_set(xfs_inode_t *ip, unsigned short flags) | ||
320 | { | ||
321 | spin_lock(&ip->i_flags_lock); | ||
322 | __xfs_iflags_set(ip, flags); | ||
323 | spin_unlock(&ip->i_flags_lock); | ||
324 | } | ||
325 | |||
326 | static inline void | ||
327 | xfs_iflags_clear(xfs_inode_t *ip, unsigned short flags) | ||
328 | { | ||
329 | spin_lock(&ip->i_flags_lock); | ||
330 | ip->i_flags &= ~flags; | ||
331 | spin_unlock(&ip->i_flags_lock); | ||
332 | } | ||
333 | |||
334 | static inline int | ||
335 | __xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | ||
336 | { | ||
337 | return (ip->i_flags & flags); | ||
338 | } | ||
339 | |||
340 | static inline int | ||
341 | xfs_iflags_test(xfs_inode_t *ip, unsigned short flags) | ||
342 | { | ||
343 | int ret; | ||
344 | spin_lock(&ip->i_flags_lock); | ||
345 | ret = __xfs_iflags_test(ip, flags); | ||
346 | spin_unlock(&ip->i_flags_lock); | ||
347 | return ret; | ||
348 | } | ||
308 | #endif /* __KERNEL__ */ | 349 | #endif /* __KERNEL__ */ |
309 | 350 | ||
310 | 351 | ||
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 061e2ffdd1de..bda774a04b8f 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -1013,7 +1013,7 @@ xfs_readlink( | |||
1013 | pathlen = (int)ip->i_d.di_size; | 1013 | pathlen = (int)ip->i_d.di_size; |
1014 | 1014 | ||
1015 | if (ip->i_df.if_flags & XFS_IFINLINE) { | 1015 | if (ip->i_df.if_flags & XFS_IFINLINE) { |
1016 | error = uio_read(ip->i_df.if_u1.if_data, pathlen, uiop); | 1016 | error = xfs_uio_read(ip->i_df.if_u1.if_data, pathlen, uiop); |
1017 | } | 1017 | } |
1018 | else { | 1018 | else { |
1019 | /* | 1019 | /* |
@@ -1044,7 +1044,7 @@ xfs_readlink( | |||
1044 | byte_cnt = pathlen; | 1044 | byte_cnt = pathlen; |
1045 | pathlen -= byte_cnt; | 1045 | pathlen -= byte_cnt; |
1046 | 1046 | ||
1047 | error = uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop); | 1047 | error = xfs_uio_read(XFS_BUF_PTR(bp), byte_cnt, uiop); |
1048 | xfs_buf_relse (bp); | 1048 | xfs_buf_relse (bp); |
1049 | } | 1049 | } |
1050 | 1050 | ||
@@ -3827,11 +3827,16 @@ xfs_reclaim( | |||
3827 | */ | 3827 | */ |
3828 | xfs_synchronize_atime(ip); | 3828 | xfs_synchronize_atime(ip); |
3829 | 3829 | ||
3830 | /* If we have nothing to flush with this inode then complete the | 3830 | /* |
3831 | * teardown now, otherwise break the link between the xfs inode | 3831 | * If we have nothing to flush with this inode then complete the |
3832 | * and the linux inode and clean up the xfs inode later. This | 3832 | * teardown now, otherwise break the link between the xfs inode and the |
3833 | * avoids flushing the inode to disk during the delete operation | 3833 | * linux inode and clean up the xfs inode later. This avoids flushing |
3834 | * itself. | 3834 | * the inode to disk during the delete operation itself. |
3835 | * | ||
3836 | * When breaking the link, we need to set the XFS_IRECLAIMABLE flag | ||
3837 | * first to ensure that xfs_iunpin() will never see an xfs inode | ||
3838 | * that has a linux inode being reclaimed. Synchronisation is provided | ||
3839 | * by the i_flags_lock. | ||
3835 | */ | 3840 | */ |
3836 | if (!ip->i_update_core && (ip->i_itemp == NULL)) { | 3841 | if (!ip->i_update_core && (ip->i_itemp == NULL)) { |
3837 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 3842 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
@@ -3840,13 +3845,13 @@ xfs_reclaim( | |||
3840 | } else { | 3845 | } else { |
3841 | xfs_mount_t *mp = ip->i_mount; | 3846 | xfs_mount_t *mp = ip->i_mount; |
3842 | 3847 | ||
3843 | /* Protect sync from us */ | 3848 | /* Protect sync and unpin from us */ |
3844 | XFS_MOUNT_ILOCK(mp); | 3849 | XFS_MOUNT_ILOCK(mp); |
3845 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); | ||
3846 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); | ||
3847 | spin_lock(&ip->i_flags_lock); | 3850 | spin_lock(&ip->i_flags_lock); |
3848 | ip->i_flags |= XFS_IRECLAIMABLE; | 3851 | __xfs_iflags_set(ip, XFS_IRECLAIMABLE); |
3852 | vn_bhv_remove(VN_BHV_HEAD(vp), XFS_ITOBHV(ip)); | ||
3849 | spin_unlock(&ip->i_flags_lock); | 3853 | spin_unlock(&ip->i_flags_lock); |
3854 | list_add_tail(&ip->i_reclaim, &mp->m_del_inodes); | ||
3850 | XFS_MOUNT_IUNLOCK(mp); | 3855 | XFS_MOUNT_IUNLOCK(mp); |
3851 | } | 3856 | } |
3852 | return 0; | 3857 | return 0; |
@@ -3872,8 +3877,8 @@ xfs_finish_reclaim( | |||
3872 | */ | 3877 | */ |
3873 | write_lock(&ih->ih_lock); | 3878 | write_lock(&ih->ih_lock); |
3874 | spin_lock(&ip->i_flags_lock); | 3879 | spin_lock(&ip->i_flags_lock); |
3875 | if ((ip->i_flags & XFS_IRECLAIM) || | 3880 | if (__xfs_iflags_test(ip, XFS_IRECLAIM) || |
3876 | (!(ip->i_flags & XFS_IRECLAIMABLE) && vp == NULL)) { | 3881 | (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) && vp == NULL)) { |
3877 | spin_unlock(&ip->i_flags_lock); | 3882 | spin_unlock(&ip->i_flags_lock); |
3878 | write_unlock(&ih->ih_lock); | 3883 | write_unlock(&ih->ih_lock); |
3879 | if (locked) { | 3884 | if (locked) { |
@@ -3882,7 +3887,7 @@ xfs_finish_reclaim( | |||
3882 | } | 3887 | } |
3883 | return 1; | 3888 | return 1; |
3884 | } | 3889 | } |
3885 | ip->i_flags |= XFS_IRECLAIM; | 3890 | __xfs_iflags_set(ip, XFS_IRECLAIM); |
3886 | spin_unlock(&ip->i_flags_lock); | 3891 | spin_unlock(&ip->i_flags_lock); |
3887 | write_unlock(&ih->ih_lock); | 3892 | write_unlock(&ih->ih_lock); |
3888 | 3893 | ||