diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_elf.c | 3 | ||||
-rw-r--r-- | fs/exec.c | 8 | ||||
-rw-r--r-- | fs/fat/file.c | 44 | ||||
-rw-r--r-- | fs/fuse/inode.c | 4 | ||||
-rw-r--r-- | fs/ocfs2/cluster/nodemanager.c | 74 | ||||
-rw-r--r-- | fs/ocfs2/cluster/nodemanager.h | 4 | ||||
-rw-r--r-- | fs/ocfs2/stack_o2cb.c | 41 | ||||
-rw-r--r-- | fs/ocfs2/stack_user.c | 3 | ||||
-rw-r--r-- | fs/ocfs2/stackglue.c | 119 | ||||
-rw-r--r-- | fs/ocfs2/stackglue.h | 19 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 83 | ||||
-rw-r--r-- | fs/udf/udfdecl.h | 2 |
12 files changed, 214 insertions, 190 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 0fa95b198e6e..d48ff5f370f4 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/mman.h> | 18 | #include <linux/mman.h> |
19 | #include <linux/a.out.h> | ||
20 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
21 | #include <linux/signal.h> | 20 | #include <linux/signal.h> |
22 | #include <linux/binfmts.h> | 21 | #include <linux/binfmts.h> |
@@ -548,7 +547,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
548 | struct { | 547 | struct { |
549 | struct elfhdr elf_ex; | 548 | struct elfhdr elf_ex; |
550 | struct elfhdr interp_elf_ex; | 549 | struct elfhdr interp_elf_ex; |
551 | struct exec interp_ex; | ||
552 | } *loc; | 550 | } *loc; |
553 | 551 | ||
554 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); | 552 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); |
@@ -680,7 +678,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
680 | } | 678 | } |
681 | 679 | ||
682 | /* Get the exec headers */ | 680 | /* Get the exec headers */ |
683 | loc->interp_ex = *((struct exec *)bprm->buf); | ||
684 | loc->interp_elf_ex = *((struct elfhdr *)bprm->buf); | 681 | loc->interp_elf_ex = *((struct elfhdr *)bprm->buf); |
685 | break; | 682 | break; |
686 | } | 683 | } |
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/file.h> | 26 | #include <linux/file.h> |
27 | #include <linux/fdtable.h> | 27 | #include <linux/fdtable.h> |
28 | #include <linux/mman.h> | 28 | #include <linux/mman.h> |
29 | #include <linux/a.out.h> | ||
30 | #include <linux/stat.h> | 29 | #include <linux/stat.h> |
31 | #include <linux/fcntl.h> | 30 | #include <linux/fcntl.h> |
32 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
@@ -61,6 +60,11 @@ | |||
61 | #include <linux/kmod.h> | 60 | #include <linux/kmod.h> |
62 | #endif | 61 | #endif |
63 | 62 | ||
63 | #ifdef __alpha__ | ||
64 | /* for /sbin/loader handling in search_binary_handler() */ | ||
65 | #include <linux/a.out.h> | ||
66 | #endif | ||
67 | |||
64 | int core_uses_pid; | 68 | int core_uses_pid; |
65 | char core_pattern[CORENAME_MAX_SIZE] = "core"; | 69 | char core_pattern[CORENAME_MAX_SIZE] = "core"; |
66 | int suid_dumpable = 0; | 70 | int suid_dumpable = 0; |
@@ -1155,7 +1159,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs) | |||
1155 | { | 1159 | { |
1156 | int try,retval; | 1160 | int try,retval; |
1157 | struct linux_binfmt *fmt; | 1161 | struct linux_binfmt *fmt; |
1158 | #if defined(__alpha__) && defined(CONFIG_ARCH_SUPPORTS_AOUT) | 1162 | #ifdef __alpha__ |
1159 | /* handle /sbin/loader.. */ | 1163 | /* handle /sbin/loader.. */ |
1160 | { | 1164 | { |
1161 | struct exec * eh = (struct exec *) bprm->buf; | 1165 | struct exec * eh = (struct exec *) bprm->buf; |
diff --git a/fs/fat/file.c b/fs/fat/file.c index 27cc1164ec36..771326b8047e 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -257,26 +257,34 @@ int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
257 | } | 257 | } |
258 | EXPORT_SYMBOL_GPL(fat_getattr); | 258 | EXPORT_SYMBOL_GPL(fat_getattr); |
259 | 259 | ||
260 | static int fat_check_mode(const struct msdos_sb_info *sbi, struct inode *inode, | 260 | static int fat_sanitize_mode(const struct msdos_sb_info *sbi, |
261 | mode_t mode) | 261 | struct inode *inode, umode_t *mode_ptr) |
262 | { | 262 | { |
263 | mode_t mask, req = mode & ~S_IFMT; | 263 | mode_t mask, perm; |
264 | 264 | ||
265 | if (S_ISREG(mode)) | 265 | /* |
266 | * Note, the basic check is already done by a caller of | ||
267 | * (attr->ia_mode & ~MSDOS_VALID_MODE) | ||
268 | */ | ||
269 | |||
270 | if (S_ISREG(inode->i_mode)) | ||
266 | mask = sbi->options.fs_fmask; | 271 | mask = sbi->options.fs_fmask; |
267 | else | 272 | else |
268 | mask = sbi->options.fs_dmask; | 273 | mask = sbi->options.fs_dmask; |
269 | 274 | ||
275 | perm = *mode_ptr & ~(S_IFMT | mask); | ||
276 | |||
270 | /* | 277 | /* |
271 | * Of the r and x bits, all (subject to umask) must be present. Of the | 278 | * Of the r and x bits, all (subject to umask) must be present. Of the |
272 | * w bits, either all (subject to umask) or none must be present. | 279 | * w bits, either all (subject to umask) or none must be present. |
273 | */ | 280 | */ |
274 | req &= ~mask; | 281 | if ((perm & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) |
275 | if ((req & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) | ||
276 | return -EPERM; | 282 | return -EPERM; |
277 | if ((req & S_IWUGO) && ((req & S_IWUGO) != (S_IWUGO & ~mask))) | 283 | if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask))) |
278 | return -EPERM; | 284 | return -EPERM; |
279 | 285 | ||
286 | *mode_ptr &= S_IFMT | perm; | ||
287 | |||
280 | return 0; | 288 | return 0; |
281 | } | 289 | } |
282 | 290 | ||
@@ -299,7 +307,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
299 | { | 307 | { |
300 | struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); | 308 | struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); |
301 | struct inode *inode = dentry->d_inode; | 309 | struct inode *inode = dentry->d_inode; |
302 | int mask, error = 0; | 310 | int error = 0; |
303 | unsigned int ia_valid; | 311 | unsigned int ia_valid; |
304 | 312 | ||
305 | lock_kernel(); | 313 | lock_kernel(); |
@@ -332,12 +340,13 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
332 | error = 0; | 340 | error = 0; |
333 | goto out; | 341 | goto out; |
334 | } | 342 | } |
343 | |||
335 | if (((attr->ia_valid & ATTR_UID) && | 344 | if (((attr->ia_valid & ATTR_UID) && |
336 | (attr->ia_uid != sbi->options.fs_uid)) || | 345 | (attr->ia_uid != sbi->options.fs_uid)) || |
337 | ((attr->ia_valid & ATTR_GID) && | 346 | ((attr->ia_valid & ATTR_GID) && |
338 | (attr->ia_gid != sbi->options.fs_gid)) || | 347 | (attr->ia_gid != sbi->options.fs_gid)) || |
339 | ((attr->ia_valid & ATTR_MODE) && | 348 | ((attr->ia_valid & ATTR_MODE) && |
340 | fat_check_mode(sbi, inode, attr->ia_mode) < 0)) | 349 | (attr->ia_mode & ~MSDOS_VALID_MODE))) |
341 | error = -EPERM; | 350 | error = -EPERM; |
342 | 351 | ||
343 | if (error) { | 352 | if (error) { |
@@ -346,15 +355,16 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) | |||
346 | goto out; | 355 | goto out; |
347 | } | 356 | } |
348 | 357 | ||
349 | error = inode_setattr(inode, attr); | 358 | /* |
350 | if (error) | 359 | * We don't return -EPERM here. Yes, strange, but this is too |
351 | goto out; | 360 | * old behavior. |
361 | */ | ||
362 | if (attr->ia_valid & ATTR_MODE) { | ||
363 | if (fat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0) | ||
364 | attr->ia_valid &= ~ATTR_MODE; | ||
365 | } | ||
352 | 366 | ||
353 | if (S_ISDIR(inode->i_mode)) | 367 | error = inode_setattr(inode, attr); |
354 | mask = sbi->options.fs_dmask; | ||
355 | else | ||
356 | mask = sbi->options.fs_fmask; | ||
357 | inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); | ||
358 | out: | 368 | out: |
359 | unlock_kernel(); | 369 | unlock_kernel(); |
360 | return error; | 370 | return error; |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 43e99513334a..3141690558c8 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -591,7 +591,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
591 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); | 591 | fc->bdi.ra_pages = min(fc->bdi.ra_pages, ra_pages); |
592 | fc->minor = arg->minor; | 592 | fc->minor = arg->minor; |
593 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; | 593 | fc->max_write = arg->minor < 5 ? 4096 : arg->max_write; |
594 | fc->max_write = min_t(unsigned, 4096, fc->max_write); | 594 | fc->max_write = max_t(unsigned, 4096, fc->max_write); |
595 | fc->conn_init = 1; | 595 | fc->conn_init = 1; |
596 | } | 596 | } |
597 | fuse_put_request(fc, req); | 597 | fuse_put_request(fc, req); |
@@ -667,7 +667,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
667 | fc->flags = d.flags; | 667 | fc->flags = d.flags; |
668 | fc->user_id = d.user_id; | 668 | fc->user_id = d.user_id; |
669 | fc->group_id = d.group_id; | 669 | fc->group_id = d.group_id; |
670 | fc->max_read = min_t(unsigned, 4096, d.max_read); | 670 | fc->max_read = max_t(unsigned, 4096, d.max_read); |
671 | 671 | ||
672 | /* Used by get_root_inode() */ | 672 | /* Used by get_root_inode() */ |
673 | sb->s_fs_info = fc; | 673 | sb->s_fs_info = fc; |
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index cf9401e8cd0b..cfdb08b484ed 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/sysctl.h> | ||
25 | #include <linux/configfs.h> | 24 | #include <linux/configfs.h> |
26 | 25 | ||
27 | #include "tcp.h" | 26 | #include "tcp.h" |
@@ -36,65 +35,6 @@ | |||
36 | * cluster references throughout where nodes are looked up */ | 35 | * cluster references throughout where nodes are looked up */ |
37 | struct o2nm_cluster *o2nm_single_cluster = NULL; | 36 | struct o2nm_cluster *o2nm_single_cluster = NULL; |
38 | 37 | ||
39 | #define OCFS2_MAX_HB_CTL_PATH 256 | ||
40 | static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl"; | ||
41 | |||
42 | static ctl_table ocfs2_nm_table[] = { | ||
43 | { | ||
44 | .ctl_name = 1, | ||
45 | .procname = "hb_ctl_path", | ||
46 | .data = ocfs2_hb_ctl_path, | ||
47 | .maxlen = OCFS2_MAX_HB_CTL_PATH, | ||
48 | .mode = 0644, | ||
49 | .proc_handler = &proc_dostring, | ||
50 | .strategy = &sysctl_string, | ||
51 | }, | ||
52 | { .ctl_name = 0 } | ||
53 | }; | ||
54 | |||
55 | static ctl_table ocfs2_mod_table[] = { | ||
56 | { | ||
57 | .ctl_name = FS_OCFS2_NM, | ||
58 | .procname = "nm", | ||
59 | .data = NULL, | ||
60 | .maxlen = 0, | ||
61 | .mode = 0555, | ||
62 | .child = ocfs2_nm_table | ||
63 | }, | ||
64 | { .ctl_name = 0} | ||
65 | }; | ||
66 | |||
67 | static ctl_table ocfs2_kern_table[] = { | ||
68 | { | ||
69 | .ctl_name = FS_OCFS2, | ||
70 | .procname = "ocfs2", | ||
71 | .data = NULL, | ||
72 | .maxlen = 0, | ||
73 | .mode = 0555, | ||
74 | .child = ocfs2_mod_table | ||
75 | }, | ||
76 | { .ctl_name = 0} | ||
77 | }; | ||
78 | |||
79 | static ctl_table ocfs2_root_table[] = { | ||
80 | { | ||
81 | .ctl_name = CTL_FS, | ||
82 | .procname = "fs", | ||
83 | .data = NULL, | ||
84 | .maxlen = 0, | ||
85 | .mode = 0555, | ||
86 | .child = ocfs2_kern_table | ||
87 | }, | ||
88 | { .ctl_name = 0 } | ||
89 | }; | ||
90 | |||
91 | static struct ctl_table_header *ocfs2_table_header = NULL; | ||
92 | |||
93 | const char *o2nm_get_hb_ctl_path(void) | ||
94 | { | ||
95 | return ocfs2_hb_ctl_path; | ||
96 | } | ||
97 | EXPORT_SYMBOL_GPL(o2nm_get_hb_ctl_path); | ||
98 | 38 | ||
99 | struct o2nm_node *o2nm_get_node_by_num(u8 node_num) | 39 | struct o2nm_node *o2nm_get_node_by_num(u8 node_num) |
100 | { | 40 | { |
@@ -941,9 +881,6 @@ void o2nm_undepend_this_node(void) | |||
941 | 881 | ||
942 | static void __exit exit_o2nm(void) | 882 | static void __exit exit_o2nm(void) |
943 | { | 883 | { |
944 | if (ocfs2_table_header) | ||
945 | unregister_sysctl_table(ocfs2_table_header); | ||
946 | |||
947 | /* XXX sync with hb callbacks and shut down hb? */ | 884 | /* XXX sync with hb callbacks and shut down hb? */ |
948 | o2net_unregister_hb_callbacks(); | 885 | o2net_unregister_hb_callbacks(); |
949 | configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); | 886 | configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); |
@@ -964,16 +901,9 @@ static int __init init_o2nm(void) | |||
964 | if (ret) | 901 | if (ret) |
965 | goto out; | 902 | goto out; |
966 | 903 | ||
967 | ocfs2_table_header = register_sysctl_table(ocfs2_root_table); | ||
968 | if (!ocfs2_table_header) { | ||
969 | printk(KERN_ERR "nodemanager: unable to register sysctl\n"); | ||
970 | ret = -ENOMEM; /* or something. */ | ||
971 | goto out_o2net; | ||
972 | } | ||
973 | |||
974 | ret = o2net_register_hb_callbacks(); | 904 | ret = o2net_register_hb_callbacks(); |
975 | if (ret) | 905 | if (ret) |
976 | goto out_sysctl; | 906 | goto out_o2net; |
977 | 907 | ||
978 | config_group_init(&o2nm_cluster_group.cs_subsys.su_group); | 908 | config_group_init(&o2nm_cluster_group.cs_subsys.su_group); |
979 | mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex); | 909 | mutex_init(&o2nm_cluster_group.cs_subsys.su_mutex); |
@@ -990,8 +920,6 @@ static int __init init_o2nm(void) | |||
990 | configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); | 920 | configfs_unregister_subsystem(&o2nm_cluster_group.cs_subsys); |
991 | out_callbacks: | 921 | out_callbacks: |
992 | o2net_unregister_hb_callbacks(); | 922 | o2net_unregister_hb_callbacks(); |
993 | out_sysctl: | ||
994 | unregister_sysctl_table(ocfs2_table_header); | ||
995 | out_o2net: | 923 | out_o2net: |
996 | o2net_exit(); | 924 | o2net_exit(); |
997 | out: | 925 | out: |
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h index 7c860361b8dd..c992ea0da4ad 100644 --- a/fs/ocfs2/cluster/nodemanager.h +++ b/fs/ocfs2/cluster/nodemanager.h | |||
@@ -33,10 +33,6 @@ | |||
33 | #include <linux/configfs.h> | 33 | #include <linux/configfs.h> |
34 | #include <linux/rbtree.h> | 34 | #include <linux/rbtree.h> |
35 | 35 | ||
36 | #define FS_OCFS2_NM 1 | ||
37 | |||
38 | const char *o2nm_get_hb_ctl_path(void); | ||
39 | |||
40 | struct o2nm_node { | 36 | struct o2nm_node { |
41 | spinlock_t nd_lock; | 37 | spinlock_t nd_lock; |
42 | struct config_item nd_item; | 38 | struct config_item nd_item; |
diff --git a/fs/ocfs2/stack_o2cb.c b/fs/ocfs2/stack_o2cb.c index bbd1667aa7d3..fcd120f1493a 100644 --- a/fs/ocfs2/stack_o2cb.c +++ b/fs/ocfs2/stack_o2cb.c | |||
@@ -317,8 +317,7 @@ out: | |||
317 | return rc; | 317 | return rc; |
318 | } | 318 | } |
319 | 319 | ||
320 | static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn, | 320 | static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn) |
321 | int hangup_pending) | ||
322 | { | 321 | { |
323 | struct dlm_ctxt *dlm = conn->cc_lockspace; | 322 | struct dlm_ctxt *dlm = conn->cc_lockspace; |
324 | struct o2dlm_private *priv = conn->cc_private; | 323 | struct o2dlm_private *priv = conn->cc_private; |
@@ -333,43 +332,6 @@ static int o2cb_cluster_disconnect(struct ocfs2_cluster_connection *conn, | |||
333 | return 0; | 332 | return 0; |
334 | } | 333 | } |
335 | 334 | ||
336 | static void o2hb_stop(const char *group) | ||
337 | { | ||
338 | int ret; | ||
339 | char *argv[5], *envp[3]; | ||
340 | |||
341 | argv[0] = (char *)o2nm_get_hb_ctl_path(); | ||
342 | argv[1] = "-K"; | ||
343 | argv[2] = "-u"; | ||
344 | argv[3] = (char *)group; | ||
345 | argv[4] = NULL; | ||
346 | |||
347 | mlog(0, "Run: %s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]); | ||
348 | |||
349 | /* minimal command environment taken from cpu_run_sbin_hotplug */ | ||
350 | envp[0] = "HOME=/"; | ||
351 | envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; | ||
352 | envp[2] = NULL; | ||
353 | |||
354 | ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); | ||
355 | if (ret < 0) | ||
356 | mlog_errno(ret); | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * Hangup is a hack for tools compatibility. Older ocfs2-tools software | ||
361 | * expects the filesystem to call "ocfs2_hb_ctl" during unmount. This | ||
362 | * happens regardless of whether the DLM got started, so we can't do it | ||
363 | * in ocfs2_cluster_disconnect(). We bring the o2hb_stop() function into | ||
364 | * the glue and provide a "hangup" API for super.c to call. | ||
365 | * | ||
366 | * Other stacks will eventually provide a NULL ->hangup() pointer. | ||
367 | */ | ||
368 | static void o2cb_cluster_hangup(const char *group, int grouplen) | ||
369 | { | ||
370 | o2hb_stop(group); | ||
371 | } | ||
372 | |||
373 | static int o2cb_cluster_this_node(unsigned int *node) | 335 | static int o2cb_cluster_this_node(unsigned int *node) |
374 | { | 336 | { |
375 | int node_num; | 337 | int node_num; |
@@ -388,7 +350,6 @@ static int o2cb_cluster_this_node(unsigned int *node) | |||
388 | static struct ocfs2_stack_operations o2cb_stack_ops = { | 350 | static struct ocfs2_stack_operations o2cb_stack_ops = { |
389 | .connect = o2cb_cluster_connect, | 351 | .connect = o2cb_cluster_connect, |
390 | .disconnect = o2cb_cluster_disconnect, | 352 | .disconnect = o2cb_cluster_disconnect, |
391 | .hangup = o2cb_cluster_hangup, | ||
392 | .this_node = o2cb_cluster_this_node, | 353 | .this_node = o2cb_cluster_this_node, |
393 | .dlm_lock = o2cb_dlm_lock, | 354 | .dlm_lock = o2cb_dlm_lock, |
394 | .dlm_unlock = o2cb_dlm_unlock, | 355 | .dlm_unlock = o2cb_dlm_unlock, |
diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index 6b97d11f6bf8..c021280dd462 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c | |||
@@ -816,8 +816,7 @@ out: | |||
816 | return rc; | 816 | return rc; |
817 | } | 817 | } |
818 | 818 | ||
819 | static int user_cluster_disconnect(struct ocfs2_cluster_connection *conn, | 819 | static int user_cluster_disconnect(struct ocfs2_cluster_connection *conn) |
820 | int hangup_pending) | ||
821 | { | 820 | { |
822 | dlm_release_lockspace(conn->cc_lockspace, 2); | 821 | dlm_release_lockspace(conn->cc_lockspace, 2); |
823 | conn->cc_lockspace = NULL; | 822 | conn->cc_lockspace = NULL; |
diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c index 119f60cea9cc..10e149ae5e3a 100644 --- a/fs/ocfs2/stackglue.c +++ b/fs/ocfs2/stackglue.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/kobject.h> | 27 | #include <linux/kobject.h> |
28 | #include <linux/sysfs.h> | 28 | #include <linux/sysfs.h> |
29 | #include <linux/sysctl.h> | ||
29 | 30 | ||
30 | #include "ocfs2_fs.h" | 31 | #include "ocfs2_fs.h" |
31 | 32 | ||
@@ -33,11 +34,13 @@ | |||
33 | 34 | ||
34 | #define OCFS2_STACK_PLUGIN_O2CB "o2cb" | 35 | #define OCFS2_STACK_PLUGIN_O2CB "o2cb" |
35 | #define OCFS2_STACK_PLUGIN_USER "user" | 36 | #define OCFS2_STACK_PLUGIN_USER "user" |
37 | #define OCFS2_MAX_HB_CTL_PATH 256 | ||
36 | 38 | ||
37 | static struct ocfs2_locking_protocol *lproto; | 39 | static struct ocfs2_locking_protocol *lproto; |
38 | static DEFINE_SPINLOCK(ocfs2_stack_lock); | 40 | static DEFINE_SPINLOCK(ocfs2_stack_lock); |
39 | static LIST_HEAD(ocfs2_stack_list); | 41 | static LIST_HEAD(ocfs2_stack_list); |
40 | static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1]; | 42 | static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1]; |
43 | static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl"; | ||
41 | 44 | ||
42 | /* | 45 | /* |
43 | * The stack currently in use. If not null, active_stack->sp_count > 0, | 46 | * The stack currently in use. If not null, active_stack->sp_count > 0, |
@@ -349,7 +352,7 @@ int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn, | |||
349 | 352 | ||
350 | BUG_ON(conn == NULL); | 353 | BUG_ON(conn == NULL); |
351 | 354 | ||
352 | ret = active_stack->sp_ops->disconnect(conn, hangup_pending); | 355 | ret = active_stack->sp_ops->disconnect(conn); |
353 | 356 | ||
354 | /* XXX Should we free it anyway? */ | 357 | /* XXX Should we free it anyway? */ |
355 | if (!ret) { | 358 | if (!ret) { |
@@ -362,13 +365,48 @@ int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn, | |||
362 | } | 365 | } |
363 | EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect); | 366 | EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect); |
364 | 367 | ||
368 | /* | ||
369 | * Leave the group for this filesystem. This is executed by a userspace | ||
370 | * program (stored in ocfs2_hb_ctl_path). | ||
371 | */ | ||
372 | static void ocfs2_leave_group(const char *group) | ||
373 | { | ||
374 | int ret; | ||
375 | char *argv[5], *envp[3]; | ||
376 | |||
377 | argv[0] = ocfs2_hb_ctl_path; | ||
378 | argv[1] = "-K"; | ||
379 | argv[2] = "-u"; | ||
380 | argv[3] = (char *)group; | ||
381 | argv[4] = NULL; | ||
382 | |||
383 | /* minimal command environment taken from cpu_run_sbin_hotplug */ | ||
384 | envp[0] = "HOME=/"; | ||
385 | envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; | ||
386 | envp[2] = NULL; | ||
387 | |||
388 | ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC); | ||
389 | if (ret < 0) { | ||
390 | printk(KERN_ERR | ||
391 | "ocfs2: Error %d running user helper " | ||
392 | "\"%s %s %s %s\"\n", | ||
393 | ret, argv[0], argv[1], argv[2], argv[3]); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * Hangup is a required post-umount. ocfs2-tools software expects the | ||
399 | * filesystem to call "ocfs2_hb_ctl" during unmount. This happens | ||
400 | * regardless of whether the DLM got started, so we can't do it | ||
401 | * in ocfs2_cluster_disconnect(). The ocfs2_leave_group() function does | ||
402 | * the actual work. | ||
403 | */ | ||
365 | void ocfs2_cluster_hangup(const char *group, int grouplen) | 404 | void ocfs2_cluster_hangup(const char *group, int grouplen) |
366 | { | 405 | { |
367 | BUG_ON(group == NULL); | 406 | BUG_ON(group == NULL); |
368 | BUG_ON(group[grouplen] != '\0'); | 407 | BUG_ON(group[grouplen] != '\0'); |
369 | 408 | ||
370 | if (active_stack->sp_ops->hangup) | 409 | ocfs2_leave_group(group); |
371 | active_stack->sp_ops->hangup(group, grouplen); | ||
372 | 410 | ||
373 | /* cluster_disconnect() was called with hangup_pending==1 */ | 411 | /* cluster_disconnect() was called with hangup_pending==1 */ |
374 | ocfs2_stack_driver_put(); | 412 | ocfs2_stack_driver_put(); |
@@ -548,10 +586,83 @@ error: | |||
548 | return ret; | 586 | return ret; |
549 | } | 587 | } |
550 | 588 | ||
589 | /* | ||
590 | * Sysctl bits | ||
591 | * | ||
592 | * The sysctl lives at /proc/sys/fs/ocfs2/nm/hb_ctl_path. The 'nm' doesn't | ||
593 | * make as much sense in a multiple cluster stack world, but it's safer | ||
594 | * and easier to preserve the name. | ||
595 | */ | ||
596 | |||
597 | #define FS_OCFS2_NM 1 | ||
598 | |||
599 | static ctl_table ocfs2_nm_table[] = { | ||
600 | { | ||
601 | .ctl_name = 1, | ||
602 | .procname = "hb_ctl_path", | ||
603 | .data = ocfs2_hb_ctl_path, | ||
604 | .maxlen = OCFS2_MAX_HB_CTL_PATH, | ||
605 | .mode = 0644, | ||
606 | .proc_handler = &proc_dostring, | ||
607 | .strategy = &sysctl_string, | ||
608 | }, | ||
609 | { .ctl_name = 0 } | ||
610 | }; | ||
611 | |||
612 | static ctl_table ocfs2_mod_table[] = { | ||
613 | { | ||
614 | .ctl_name = FS_OCFS2_NM, | ||
615 | .procname = "nm", | ||
616 | .data = NULL, | ||
617 | .maxlen = 0, | ||
618 | .mode = 0555, | ||
619 | .child = ocfs2_nm_table | ||
620 | }, | ||
621 | { .ctl_name = 0} | ||
622 | }; | ||
623 | |||
624 | static ctl_table ocfs2_kern_table[] = { | ||
625 | { | ||
626 | .ctl_name = FS_OCFS2, | ||
627 | .procname = "ocfs2", | ||
628 | .data = NULL, | ||
629 | .maxlen = 0, | ||
630 | .mode = 0555, | ||
631 | .child = ocfs2_mod_table | ||
632 | }, | ||
633 | { .ctl_name = 0} | ||
634 | }; | ||
635 | |||
636 | static ctl_table ocfs2_root_table[] = { | ||
637 | { | ||
638 | .ctl_name = CTL_FS, | ||
639 | .procname = "fs", | ||
640 | .data = NULL, | ||
641 | .maxlen = 0, | ||
642 | .mode = 0555, | ||
643 | .child = ocfs2_kern_table | ||
644 | }, | ||
645 | { .ctl_name = 0 } | ||
646 | }; | ||
647 | |||
648 | static struct ctl_table_header *ocfs2_table_header = NULL; | ||
649 | |||
650 | |||
651 | /* | ||
652 | * Initialization | ||
653 | */ | ||
654 | |||
551 | static int __init ocfs2_stack_glue_init(void) | 655 | static int __init ocfs2_stack_glue_init(void) |
552 | { | 656 | { |
553 | strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB); | 657 | strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB); |
554 | 658 | ||
659 | ocfs2_table_header = register_sysctl_table(ocfs2_root_table); | ||
660 | if (!ocfs2_table_header) { | ||
661 | printk(KERN_ERR | ||
662 | "ocfs2 stack glue: unable to register sysctl\n"); | ||
663 | return -ENOMEM; /* or something. */ | ||
664 | } | ||
665 | |||
555 | return ocfs2_sysfs_init(); | 666 | return ocfs2_sysfs_init(); |
556 | } | 667 | } |
557 | 668 | ||
@@ -559,6 +670,8 @@ static void __exit ocfs2_stack_glue_exit(void) | |||
559 | { | 670 | { |
560 | lproto = NULL; | 671 | lproto = NULL; |
561 | ocfs2_sysfs_exit(); | 672 | ocfs2_sysfs_exit(); |
673 | if (ocfs2_table_header) | ||
674 | unregister_sysctl_table(ocfs2_table_header); | ||
562 | } | 675 | } |
563 | 676 | ||
564 | MODULE_AUTHOR("Oracle"); | 677 | MODULE_AUTHOR("Oracle"); |
diff --git a/fs/ocfs2/stackglue.h b/fs/ocfs2/stackglue.h index 005e4f170e0f..db56281dd1be 100644 --- a/fs/ocfs2/stackglue.h +++ b/fs/ocfs2/stackglue.h | |||
@@ -134,22 +134,10 @@ struct ocfs2_stack_operations { | |||
134 | * be freed. Thus, a stack must not return from ->disconnect() | 134 | * be freed. Thus, a stack must not return from ->disconnect() |
135 | * until it will no longer reference the conn pointer. | 135 | * until it will no longer reference the conn pointer. |
136 | * | 136 | * |
137 | * If hangup_pending is zero, ocfs2_cluster_disconnect() will also | 137 | * Once this call returns, the stack glue will be dropping this |
138 | * be dropping the reference on the module. | 138 | * connection's reference on the module. |
139 | */ | 139 | */ |
140 | int (*disconnect)(struct ocfs2_cluster_connection *conn, | 140 | int (*disconnect)(struct ocfs2_cluster_connection *conn); |
141 | int hangup_pending); | ||
142 | |||
143 | /* | ||
144 | * ocfs2_cluster_hangup() exists for compatibility with older | ||
145 | * ocfs2 tools. Only the classic stack really needs it. As such | ||
146 | * ->hangup() is not required of all stacks. See the comment by | ||
147 | * ocfs2_cluster_hangup() for more details. | ||
148 | * | ||
149 | * Note that ocfs2_cluster_hangup() can only be called if | ||
150 | * hangup_pending was passed to ocfs2_cluster_disconnect(). | ||
151 | */ | ||
152 | void (*hangup)(const char *group, int grouplen); | ||
153 | 141 | ||
154 | /* | 142 | /* |
155 | * ->this_node() returns the cluster's unique identifier for the | 143 | * ->this_node() returns the cluster's unique identifier for the |
@@ -258,4 +246,5 @@ void ocfs2_stack_glue_set_locking_protocol(struct ocfs2_locking_protocol *proto) | |||
258 | /* Used by stack plugins */ | 246 | /* Used by stack plugins */ |
259 | int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin); | 247 | int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin); |
260 | void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin); | 248 | void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin); |
249 | |||
261 | #endif /* STACKGLUE_H */ | 250 | #endif /* STACKGLUE_H */ |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 17403629e330..ab8ccc9d14ff 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -315,9 +315,9 @@ struct mem_size_stats { | |||
315 | }; | 315 | }; |
316 | 316 | ||
317 | static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | 317 | static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, |
318 | void *private) | 318 | struct mm_walk *walk) |
319 | { | 319 | { |
320 | struct mem_size_stats *mss = private; | 320 | struct mem_size_stats *mss = walk->private; |
321 | struct vm_area_struct *vma = mss->vma; | 321 | struct vm_area_struct *vma = mss->vma; |
322 | pte_t *pte, ptent; | 322 | pte_t *pte, ptent; |
323 | spinlock_t *ptl; | 323 | spinlock_t *ptl; |
@@ -365,19 +365,21 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | |||
365 | return 0; | 365 | return 0; |
366 | } | 366 | } |
367 | 367 | ||
368 | static struct mm_walk smaps_walk = { .pmd_entry = smaps_pte_range }; | ||
369 | |||
370 | static int show_smap(struct seq_file *m, void *v) | 368 | static int show_smap(struct seq_file *m, void *v) |
371 | { | 369 | { |
372 | struct vm_area_struct *vma = v; | 370 | struct vm_area_struct *vma = v; |
373 | struct mem_size_stats mss; | 371 | struct mem_size_stats mss; |
374 | int ret; | 372 | int ret; |
373 | struct mm_walk smaps_walk = { | ||
374 | .pmd_entry = smaps_pte_range, | ||
375 | .mm = vma->vm_mm, | ||
376 | .private = &mss, | ||
377 | }; | ||
375 | 378 | ||
376 | memset(&mss, 0, sizeof mss); | 379 | memset(&mss, 0, sizeof mss); |
377 | mss.vma = vma; | 380 | mss.vma = vma; |
378 | if (vma->vm_mm && !is_vm_hugetlb_page(vma)) | 381 | if (vma->vm_mm && !is_vm_hugetlb_page(vma)) |
379 | walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end, | 382 | walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk); |
380 | &smaps_walk, &mss); | ||
381 | 383 | ||
382 | ret = show_map(m, v); | 384 | ret = show_map(m, v); |
383 | if (ret) | 385 | if (ret) |
@@ -426,9 +428,9 @@ const struct file_operations proc_smaps_operations = { | |||
426 | }; | 428 | }; |
427 | 429 | ||
428 | static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, | 430 | static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, |
429 | unsigned long end, void *private) | 431 | unsigned long end, struct mm_walk *walk) |
430 | { | 432 | { |
431 | struct vm_area_struct *vma = private; | 433 | struct vm_area_struct *vma = walk->private; |
432 | pte_t *pte, ptent; | 434 | pte_t *pte, ptent; |
433 | spinlock_t *ptl; | 435 | spinlock_t *ptl; |
434 | struct page *page; | 436 | struct page *page; |
@@ -452,8 +454,6 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, | |||
452 | return 0; | 454 | return 0; |
453 | } | 455 | } |
454 | 456 | ||
455 | static struct mm_walk clear_refs_walk = { .pmd_entry = clear_refs_pte_range }; | ||
456 | |||
457 | static ssize_t clear_refs_write(struct file *file, const char __user *buf, | 457 | static ssize_t clear_refs_write(struct file *file, const char __user *buf, |
458 | size_t count, loff_t *ppos) | 458 | size_t count, loff_t *ppos) |
459 | { | 459 | { |
@@ -476,11 +476,17 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, | |||
476 | return -ESRCH; | 476 | return -ESRCH; |
477 | mm = get_task_mm(task); | 477 | mm = get_task_mm(task); |
478 | if (mm) { | 478 | if (mm) { |
479 | static struct mm_walk clear_refs_walk; | ||
480 | memset(&clear_refs_walk, 0, sizeof(clear_refs_walk)); | ||
481 | clear_refs_walk.pmd_entry = clear_refs_pte_range; | ||
482 | clear_refs_walk.mm = mm; | ||
479 | down_read(&mm->mmap_sem); | 483 | down_read(&mm->mmap_sem); |
480 | for (vma = mm->mmap; vma; vma = vma->vm_next) | 484 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
485 | clear_refs_walk.private = vma; | ||
481 | if (!is_vm_hugetlb_page(vma)) | 486 | if (!is_vm_hugetlb_page(vma)) |
482 | walk_page_range(mm, vma->vm_start, vma->vm_end, | 487 | walk_page_range(vma->vm_start, vma->vm_end, |
483 | &clear_refs_walk, vma); | 488 | &clear_refs_walk); |
489 | } | ||
484 | flush_tlb_mm(mm); | 490 | flush_tlb_mm(mm); |
485 | up_read(&mm->mmap_sem); | 491 | up_read(&mm->mmap_sem); |
486 | mmput(mm); | 492 | mmput(mm); |
@@ -528,9 +534,9 @@ static int add_to_pagemap(unsigned long addr, u64 pfn, | |||
528 | } | 534 | } |
529 | 535 | ||
530 | static int pagemap_pte_hole(unsigned long start, unsigned long end, | 536 | static int pagemap_pte_hole(unsigned long start, unsigned long end, |
531 | void *private) | 537 | struct mm_walk *walk) |
532 | { | 538 | { |
533 | struct pagemapread *pm = private; | 539 | struct pagemapread *pm = walk->private; |
534 | unsigned long addr; | 540 | unsigned long addr; |
535 | int err = 0; | 541 | int err = 0; |
536 | for (addr = start; addr < end; addr += PAGE_SIZE) { | 542 | for (addr = start; addr < end; addr += PAGE_SIZE) { |
@@ -547,24 +553,45 @@ static u64 swap_pte_to_pagemap_entry(pte_t pte) | |||
547 | return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); | 553 | return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); |
548 | } | 554 | } |
549 | 555 | ||
556 | static unsigned long pte_to_pagemap_entry(pte_t pte) | ||
557 | { | ||
558 | unsigned long pme = 0; | ||
559 | if (is_swap_pte(pte)) | ||
560 | pme = PM_PFRAME(swap_pte_to_pagemap_entry(pte)) | ||
561 | | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; | ||
562 | else if (pte_present(pte)) | ||
563 | pme = PM_PFRAME(pte_pfn(pte)) | ||
564 | | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; | ||
565 | return pme; | ||
566 | } | ||
567 | |||
550 | static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, | 568 | static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, |
551 | void *private) | 569 | struct mm_walk *walk) |
552 | { | 570 | { |
553 | struct pagemapread *pm = private; | 571 | struct vm_area_struct *vma; |
572 | struct pagemapread *pm = walk->private; | ||
554 | pte_t *pte; | 573 | pte_t *pte; |
555 | int err = 0; | 574 | int err = 0; |
556 | 575 | ||
576 | /* find the first VMA at or above 'addr' */ | ||
577 | vma = find_vma(walk->mm, addr); | ||
557 | for (; addr != end; addr += PAGE_SIZE) { | 578 | for (; addr != end; addr += PAGE_SIZE) { |
558 | u64 pfn = PM_NOT_PRESENT; | 579 | u64 pfn = PM_NOT_PRESENT; |
559 | pte = pte_offset_map(pmd, addr); | 580 | |
560 | if (is_swap_pte(*pte)) | 581 | /* check to see if we've left 'vma' behind |
561 | pfn = PM_PFRAME(swap_pte_to_pagemap_entry(*pte)) | 582 | * and need a new, higher one */ |
562 | | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; | 583 | if (vma && (addr >= vma->vm_end)) |
563 | else if (pte_present(*pte)) | 584 | vma = find_vma(walk->mm, addr); |
564 | pfn = PM_PFRAME(pte_pfn(*pte)) | 585 | |
565 | | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; | 586 | /* check that 'vma' actually covers this address, |
566 | /* unmap so we're not in atomic when we copy to userspace */ | 587 | * and that it isn't a huge page vma */ |
567 | pte_unmap(pte); | 588 | if (vma && (vma->vm_start <= addr) && |
589 | !is_vm_hugetlb_page(vma)) { | ||
590 | pte = pte_offset_map(pmd, addr); | ||
591 | pfn = pte_to_pagemap_entry(*pte); | ||
592 | /* unmap before userspace copy */ | ||
593 | pte_unmap(pte); | ||
594 | } | ||
568 | err = add_to_pagemap(addr, pfn, pm); | 595 | err = add_to_pagemap(addr, pfn, pm); |
569 | if (err) | 596 | if (err) |
570 | return err; | 597 | return err; |
@@ -675,8 +702,8 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, | |||
675 | * user buffer is tracked in "pm", and the walk | 702 | * user buffer is tracked in "pm", and the walk |
676 | * will stop when we hit the end of the buffer. | 703 | * will stop when we hit the end of the buffer. |
677 | */ | 704 | */ |
678 | ret = walk_page_range(mm, start_vaddr, end_vaddr, | 705 | ret = walk_page_range(start_vaddr, end_vaddr, |
679 | &pagemap_walk, &pm); | 706 | &pagemap_walk); |
680 | if (ret == PM_END_OF_BUFFER) | 707 | if (ret == PM_END_OF_BUFFER) |
681 | ret = 0; | 708 | ret = 0; |
682 | /* don't need mmap_sem for these, but this looks cleaner */ | 709 | /* don't need mmap_sem for these, but this looks cleaner */ |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 8fa9c2d70911..8ec865de5f13 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #define UDF_PREALLOCATE | 16 | #define UDF_PREALLOCATE |
17 | #define UDF_DEFAULT_PREALLOC_BLOCKS 8 | 17 | #define UDF_DEFAULT_PREALLOC_BLOCKS 8 |
18 | 18 | ||
19 | #define UDFFS_DEBUG | 19 | #undef UDFFS_DEBUG |
20 | 20 | ||
21 | #ifdef UDFFS_DEBUG | 21 | #ifdef UDFFS_DEBUG |
22 | #define udf_debug(f, a...) \ | 22 | #define udf_debug(f, a...) \ |