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...) \ |
