diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/char_dev.c | 18 | ||||
-rw-r--r-- | fs/coredump.c | 5 | ||||
-rw-r--r-- | fs/ext2/super.c | 4 | ||||
-rw-r--r-- | fs/ext3/namei.c | 40 | ||||
-rw-r--r-- | fs/ext3/namei.h | 19 | ||||
-rw-r--r-- | fs/ext3/super.c | 4 | ||||
-rw-r--r-- | fs/lockd/clntxdr.c | 2 | ||||
-rw-r--r-- | fs/lockd/svcproc.c | 3 | ||||
-rw-r--r-- | fs/proc/internal.h | 4 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 53 | ||||
-rw-r--r-- | fs/quota/dquot.c | 2 | ||||
-rw-r--r-- | fs/xattr.c | 2 |
12 files changed, 124 insertions, 32 deletions
diff --git a/fs/char_dev.c b/fs/char_dev.c index 3f152b92a94a..afc2bb691780 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -471,9 +471,19 @@ static int exact_lock(dev_t dev, void *data) | |||
471 | */ | 471 | */ |
472 | int cdev_add(struct cdev *p, dev_t dev, unsigned count) | 472 | int cdev_add(struct cdev *p, dev_t dev, unsigned count) |
473 | { | 473 | { |
474 | int error; | ||
475 | |||
474 | p->dev = dev; | 476 | p->dev = dev; |
475 | p->count = count; | 477 | p->count = count; |
476 | return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p); | 478 | |
479 | error = kobj_map(cdev_map, dev, count, NULL, | ||
480 | exact_match, exact_lock, p); | ||
481 | if (error) | ||
482 | return error; | ||
483 | |||
484 | kobject_get(p->kobj.parent); | ||
485 | |||
486 | return 0; | ||
477 | } | 487 | } |
478 | 488 | ||
479 | static void cdev_unmap(dev_t dev, unsigned count) | 489 | static void cdev_unmap(dev_t dev, unsigned count) |
@@ -498,14 +508,20 @@ void cdev_del(struct cdev *p) | |||
498 | static void cdev_default_release(struct kobject *kobj) | 508 | static void cdev_default_release(struct kobject *kobj) |
499 | { | 509 | { |
500 | struct cdev *p = container_of(kobj, struct cdev, kobj); | 510 | struct cdev *p = container_of(kobj, struct cdev, kobj); |
511 | struct kobject *parent = kobj->parent; | ||
512 | |||
501 | cdev_purge(p); | 513 | cdev_purge(p); |
514 | kobject_put(parent); | ||
502 | } | 515 | } |
503 | 516 | ||
504 | static void cdev_dynamic_release(struct kobject *kobj) | 517 | static void cdev_dynamic_release(struct kobject *kobj) |
505 | { | 518 | { |
506 | struct cdev *p = container_of(kobj, struct cdev, kobj); | 519 | struct cdev *p = container_of(kobj, struct cdev, kobj); |
520 | struct kobject *parent = kobj->parent; | ||
521 | |||
507 | cdev_purge(p); | 522 | cdev_purge(p); |
508 | kfree(p); | 523 | kfree(p); |
524 | kobject_put(parent); | ||
509 | } | 525 | } |
510 | 526 | ||
511 | static struct kobj_type ktype_cdev_default = { | 527 | static struct kobj_type ktype_cdev_default = { |
diff --git a/fs/coredump.c b/fs/coredump.c index fd37facac8dc..ce47379bfa61 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -450,11 +450,12 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) | |||
450 | 450 | ||
451 | cp->file = files[1]; | 451 | cp->file = files[1]; |
452 | 452 | ||
453 | replace_fd(0, files[0], 0); | 453 | err = replace_fd(0, files[0], 0); |
454 | fput(files[0]); | ||
454 | /* and disallow core files too */ | 455 | /* and disallow core files too */ |
455 | current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; | 456 | current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; |
456 | 457 | ||
457 | return 0; | 458 | return err; |
458 | } | 459 | } |
459 | 460 | ||
460 | void do_coredump(siginfo_t *siginfo, struct pt_regs *regs) | 461 | void do_coredump(siginfo_t *siginfo, struct pt_regs *regs) |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 6c205d0c565b..fa04d023177e 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -469,7 +469,7 @@ static int parse_options(char *options, struct super_block *sb) | |||
469 | uid = make_kuid(current_user_ns(), option); | 469 | uid = make_kuid(current_user_ns(), option); |
470 | if (!uid_valid(uid)) { | 470 | if (!uid_valid(uid)) { |
471 | ext2_msg(sb, KERN_ERR, "Invalid uid value %d", option); | 471 | ext2_msg(sb, KERN_ERR, "Invalid uid value %d", option); |
472 | return -1; | 472 | return 0; |
473 | 473 | ||
474 | } | 474 | } |
475 | sbi->s_resuid = uid; | 475 | sbi->s_resuid = uid; |
@@ -480,7 +480,7 @@ static int parse_options(char *options, struct super_block *sb) | |||
480 | gid = make_kgid(current_user_ns(), option); | 480 | gid = make_kgid(current_user_ns(), option); |
481 | if (!gid_valid(gid)) { | 481 | if (!gid_valid(gid)) { |
482 | ext2_msg(sb, KERN_ERR, "Invalid gid value %d", option); | 482 | ext2_msg(sb, KERN_ERR, "Invalid gid value %d", option); |
483 | return -1; | 483 | return 0; |
484 | } | 484 | } |
485 | sbi->s_resgid = gid; | 485 | sbi->s_resgid = gid; |
486 | break; | 486 | break; |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 8f4fddac01a6..890b8947c546 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -46,8 +46,7 @@ static struct buffer_head *ext3_append(handle_t *handle, | |||
46 | 46 | ||
47 | *block = inode->i_size >> inode->i_sb->s_blocksize_bits; | 47 | *block = inode->i_size >> inode->i_sb->s_blocksize_bits; |
48 | 48 | ||
49 | bh = ext3_bread(handle, inode, *block, 1, err); | 49 | if ((bh = ext3_dir_bread(handle, inode, *block, 1, err))) { |
50 | if (bh) { | ||
51 | inode->i_size += inode->i_sb->s_blocksize; | 50 | inode->i_size += inode->i_sb->s_blocksize; |
52 | EXT3_I(inode)->i_disksize = inode->i_size; | 51 | EXT3_I(inode)->i_disksize = inode->i_size; |
53 | *err = ext3_journal_get_write_access(handle, bh); | 52 | *err = ext3_journal_get_write_access(handle, bh); |
@@ -339,8 +338,10 @@ dx_probe(struct qstr *entry, struct inode *dir, | |||
339 | u32 hash; | 338 | u32 hash; |
340 | 339 | ||
341 | frame->bh = NULL; | 340 | frame->bh = NULL; |
342 | if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) | 341 | if (!(bh = ext3_dir_bread(NULL, dir, 0, 0, err))) { |
342 | *err = ERR_BAD_DX_DIR; | ||
343 | goto fail; | 343 | goto fail; |
344 | } | ||
344 | root = (struct dx_root *) bh->b_data; | 345 | root = (struct dx_root *) bh->b_data; |
345 | if (root->info.hash_version != DX_HASH_TEA && | 346 | if (root->info.hash_version != DX_HASH_TEA && |
346 | root->info.hash_version != DX_HASH_HALF_MD4 && | 347 | root->info.hash_version != DX_HASH_HALF_MD4 && |
@@ -436,8 +437,10 @@ dx_probe(struct qstr *entry, struct inode *dir, | |||
436 | frame->entries = entries; | 437 | frame->entries = entries; |
437 | frame->at = at; | 438 | frame->at = at; |
438 | if (!indirect--) return frame; | 439 | if (!indirect--) return frame; |
439 | if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) | 440 | if (!(bh = ext3_dir_bread(NULL, dir, dx_get_block(at), 0, err))) { |
441 | *err = ERR_BAD_DX_DIR; | ||
440 | goto fail2; | 442 | goto fail2; |
443 | } | ||
441 | at = entries = ((struct dx_node *) bh->b_data)->entries; | 444 | at = entries = ((struct dx_node *) bh->b_data)->entries; |
442 | if (dx_get_limit(entries) != dx_node_limit (dir)) { | 445 | if (dx_get_limit(entries) != dx_node_limit (dir)) { |
443 | ext3_warning(dir->i_sb, __func__, | 446 | ext3_warning(dir->i_sb, __func__, |
@@ -535,8 +538,8 @@ static int ext3_htree_next_block(struct inode *dir, __u32 hash, | |||
535 | * block so no check is necessary | 538 | * block so no check is necessary |
536 | */ | 539 | */ |
537 | while (num_frames--) { | 540 | while (num_frames--) { |
538 | if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), | 541 | if (!(bh = ext3_dir_bread(NULL, dir, dx_get_block(p->at), |
539 | 0, &err))) | 542 | 0, &err))) |
540 | return err; /* Failure */ | 543 | return err; /* Failure */ |
541 | p++; | 544 | p++; |
542 | brelse (p->bh); | 545 | brelse (p->bh); |
@@ -559,10 +562,11 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
559 | { | 562 | { |
560 | struct buffer_head *bh; | 563 | struct buffer_head *bh; |
561 | struct ext3_dir_entry_2 *de, *top; | 564 | struct ext3_dir_entry_2 *de, *top; |
562 | int err, count = 0; | 565 | int err = 0, count = 0; |
563 | 566 | ||
564 | dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); | 567 | dxtrace(printk("In htree dirblock_to_tree: block %d\n", block)); |
565 | if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) | 568 | |
569 | if (!(bh = ext3_dir_bread(NULL, dir, block, 0, &err))) | ||
566 | return err; | 570 | return err; |
567 | 571 | ||
568 | de = (struct ext3_dir_entry_2 *) bh->b_data; | 572 | de = (struct ext3_dir_entry_2 *) bh->b_data; |
@@ -976,7 +980,7 @@ static struct buffer_head * ext3_dx_find_entry(struct inode *dir, | |||
976 | return NULL; | 980 | return NULL; |
977 | do { | 981 | do { |
978 | block = dx_get_block(frame->at); | 982 | block = dx_get_block(frame->at); |
979 | if (!(bh = ext3_bread (NULL,dir, block, 0, err))) | 983 | if (!(bh = ext3_dir_bread (NULL, dir, block, 0, err))) |
980 | goto errout; | 984 | goto errout; |
981 | 985 | ||
982 | retval = search_dirblock(bh, dir, entry, | 986 | retval = search_dirblock(bh, dir, entry, |
@@ -1458,9 +1462,9 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, | |||
1458 | } | 1462 | } |
1459 | blocks = dir->i_size >> sb->s_blocksize_bits; | 1463 | blocks = dir->i_size >> sb->s_blocksize_bits; |
1460 | for (block = 0; block < blocks; block++) { | 1464 | for (block = 0; block < blocks; block++) { |
1461 | bh = ext3_bread(handle, dir, block, 0, &retval); | 1465 | if (!(bh = ext3_dir_bread(handle, dir, block, 0, &retval))) |
1462 | if(!bh) | ||
1463 | return retval; | 1466 | return retval; |
1467 | |||
1464 | retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh); | 1468 | retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh); |
1465 | if (retval != -ENOSPC) | 1469 | if (retval != -ENOSPC) |
1466 | return retval; | 1470 | return retval; |
@@ -1500,7 +1504,7 @@ static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, | |||
1500 | entries = frame->entries; | 1504 | entries = frame->entries; |
1501 | at = frame->at; | 1505 | at = frame->at; |
1502 | 1506 | ||
1503 | if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) | 1507 | if (!(bh = ext3_dir_bread(handle, dir, dx_get_block(frame->at), 0, &err))) |
1504 | goto cleanup; | 1508 | goto cleanup; |
1505 | 1509 | ||
1506 | BUFFER_TRACE(bh, "get_write_access"); | 1510 | BUFFER_TRACE(bh, "get_write_access"); |
@@ -1790,8 +1794,7 @@ retry: | |||
1790 | inode->i_op = &ext3_dir_inode_operations; | 1794 | inode->i_op = &ext3_dir_inode_operations; |
1791 | inode->i_fop = &ext3_dir_operations; | 1795 | inode->i_fop = &ext3_dir_operations; |
1792 | inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; | 1796 | inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; |
1793 | dir_block = ext3_bread (handle, inode, 0, 1, &err); | 1797 | if (!(dir_block = ext3_dir_bread(handle, inode, 0, 1, &err))) |
1794 | if (!dir_block) | ||
1795 | goto out_clear_inode; | 1798 | goto out_clear_inode; |
1796 | 1799 | ||
1797 | BUFFER_TRACE(dir_block, "get_write_access"); | 1800 | BUFFER_TRACE(dir_block, "get_write_access"); |
@@ -1859,7 +1862,7 @@ static int empty_dir (struct inode * inode) | |||
1859 | 1862 | ||
1860 | sb = inode->i_sb; | 1863 | sb = inode->i_sb; |
1861 | if (inode->i_size < EXT3_DIR_REC_LEN(1) + EXT3_DIR_REC_LEN(2) || | 1864 | if (inode->i_size < EXT3_DIR_REC_LEN(1) + EXT3_DIR_REC_LEN(2) || |
1862 | !(bh = ext3_bread (NULL, inode, 0, 0, &err))) { | 1865 | !(bh = ext3_dir_bread(NULL, inode, 0, 0, &err))) { |
1863 | if (err) | 1866 | if (err) |
1864 | ext3_error(inode->i_sb, __func__, | 1867 | ext3_error(inode->i_sb, __func__, |
1865 | "error %d reading directory #%lu offset 0", | 1868 | "error %d reading directory #%lu offset 0", |
@@ -1890,9 +1893,8 @@ static int empty_dir (struct inode * inode) | |||
1890 | (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) { | 1893 | (void *) de >= (void *) (bh->b_data+sb->s_blocksize)) { |
1891 | err = 0; | 1894 | err = 0; |
1892 | brelse (bh); | 1895 | brelse (bh); |
1893 | bh = ext3_bread (NULL, inode, | 1896 | if (!(bh = ext3_dir_bread (NULL, inode, |
1894 | offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err); | 1897 | offset >> EXT3_BLOCK_SIZE_BITS(sb), 0, &err))) { |
1895 | if (!bh) { | ||
1896 | if (err) | 1898 | if (err) |
1897 | ext3_error(sb, __func__, | 1899 | ext3_error(sb, __func__, |
1898 | "error %d reading directory" | 1900 | "error %d reading directory" |
@@ -2388,7 +2390,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2388 | goto end_rename; | 2390 | goto end_rename; |
2389 | } | 2391 | } |
2390 | retval = -EIO; | 2392 | retval = -EIO; |
2391 | dir_bh = ext3_bread (handle, old_inode, 0, 0, &retval); | 2393 | dir_bh = ext3_dir_bread(handle, old_inode, 0, 0, &retval); |
2392 | if (!dir_bh) | 2394 | if (!dir_bh) |
2393 | goto end_rename; | 2395 | goto end_rename; |
2394 | if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino) | 2396 | if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino) |
diff --git a/fs/ext3/namei.h b/fs/ext3/namei.h index f2ce2b0065c9..46304d8c9f0a 100644 --- a/fs/ext3/namei.h +++ b/fs/ext3/namei.h | |||
@@ -6,3 +6,22 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | extern struct dentry *ext3_get_parent(struct dentry *child); | 8 | extern struct dentry *ext3_get_parent(struct dentry *child); |
9 | |||
10 | static inline struct buffer_head *ext3_dir_bread(handle_t *handle, | ||
11 | struct inode *inode, | ||
12 | int block, int create, | ||
13 | int *err) | ||
14 | { | ||
15 | struct buffer_head *bh; | ||
16 | |||
17 | bh = ext3_bread(handle, inode, block, create, err); | ||
18 | |||
19 | if (!bh && !(*err)) { | ||
20 | *err = -EIO; | ||
21 | ext3_error(inode->i_sb, __func__, | ||
22 | "Directory hole detected on inode %lu\n", | ||
23 | inode->i_ino); | ||
24 | return NULL; | ||
25 | } | ||
26 | return bh; | ||
27 | } | ||
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 29e79713c7eb..5366393528df 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -1001,7 +1001,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
1001 | uid = make_kuid(current_user_ns(), option); | 1001 | uid = make_kuid(current_user_ns(), option); |
1002 | if (!uid_valid(uid)) { | 1002 | if (!uid_valid(uid)) { |
1003 | ext3_msg(sb, KERN_ERR, "Invalid uid value %d", option); | 1003 | ext3_msg(sb, KERN_ERR, "Invalid uid value %d", option); |
1004 | return -1; | 1004 | return 0; |
1005 | 1005 | ||
1006 | } | 1006 | } |
1007 | sbi->s_resuid = uid; | 1007 | sbi->s_resuid = uid; |
@@ -1012,7 +1012,7 @@ static int parse_options (char *options, struct super_block *sb, | |||
1012 | gid = make_kgid(current_user_ns(), option); | 1012 | gid = make_kgid(current_user_ns(), option); |
1013 | if (!gid_valid(gid)) { | 1013 | if (!gid_valid(gid)) { |
1014 | ext3_msg(sb, KERN_ERR, "Invalid gid value %d", option); | 1014 | ext3_msg(sb, KERN_ERR, "Invalid gid value %d", option); |
1015 | return -1; | 1015 | return 0; |
1016 | } | 1016 | } |
1017 | sbi->s_resgid = gid; | 1017 | sbi->s_resgid = gid; |
1018 | break; | 1018 | break; |
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index d269ada7670e..982d2676e1f8 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c | |||
@@ -223,7 +223,7 @@ static void encode_nlm_stat(struct xdr_stream *xdr, | |||
223 | { | 223 | { |
224 | __be32 *p; | 224 | __be32 *p; |
225 | 225 | ||
226 | BUG_ON(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); | 226 | WARN_ON_ONCE(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); |
227 | p = xdr_reserve_space(xdr, 4); | 227 | p = xdr_reserve_space(xdr, 4); |
228 | *p = stat; | 228 | *p = stat; |
229 | } | 229 | } |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 3009a365e082..21171f0c6477 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -68,7 +68,8 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
68 | 68 | ||
69 | /* Obtain file pointer. Not used by FREE_ALL call. */ | 69 | /* Obtain file pointer. Not used by FREE_ALL call. */ |
70 | if (filp != NULL) { | 70 | if (filp != NULL) { |
71 | if ((error = nlm_lookup_file(rqstp, &file, &lock->fh)) != 0) | 71 | error = cast_status(nlm_lookup_file(rqstp, &file, &lock->fh)); |
72 | if (error != 0) | ||
72 | goto no_locks; | 73 | goto no_locks; |
73 | *filp = file; | 74 | *filp = file; |
74 | 75 | ||
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index cceaab07ad54..43973b084abf 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/proc_fs.h> | 13 | #include <linux/proc_fs.h> |
14 | struct ctl_table_header; | 14 | struct ctl_table_header; |
15 | struct mempolicy; | ||
15 | 16 | ||
16 | extern struct proc_dir_entry proc_root; | 17 | extern struct proc_dir_entry proc_root; |
17 | #ifdef CONFIG_PROC_SYSCTL | 18 | #ifdef CONFIG_PROC_SYSCTL |
@@ -74,6 +75,9 @@ struct proc_maps_private { | |||
74 | #ifdef CONFIG_MMU | 75 | #ifdef CONFIG_MMU |
75 | struct vm_area_struct *tail_vma; | 76 | struct vm_area_struct *tail_vma; |
76 | #endif | 77 | #endif |
78 | #ifdef CONFIG_NUMA | ||
79 | struct mempolicy *task_mempolicy; | ||
80 | #endif | ||
77 | }; | 81 | }; |
78 | 82 | ||
79 | void proc_init_inodecache(void); | 83 | void proc_init_inodecache(void); |
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 79827ce03e3b..90c63f9392a5 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -90,10 +90,55 @@ static void pad_len_spaces(struct seq_file *m, int len) | |||
90 | seq_printf(m, "%*c", len, ' '); | 90 | seq_printf(m, "%*c", len, ' '); |
91 | } | 91 | } |
92 | 92 | ||
93 | #ifdef CONFIG_NUMA | ||
94 | /* | ||
95 | * These functions are for numa_maps but called in generic **maps seq_file | ||
96 | * ->start(), ->stop() ops. | ||
97 | * | ||
98 | * numa_maps scans all vmas under mmap_sem and checks their mempolicy. | ||
99 | * Each mempolicy object is controlled by reference counting. The problem here | ||
100 | * is how to avoid accessing dead mempolicy object. | ||
101 | * | ||
102 | * Because we're holding mmap_sem while reading seq_file, it's safe to access | ||
103 | * each vma's mempolicy, no vma objects will never drop refs to mempolicy. | ||
104 | * | ||
105 | * A task's mempolicy (task->mempolicy) has different behavior. task->mempolicy | ||
106 | * is set and replaced under mmap_sem but unrefed and cleared under task_lock(). | ||
107 | * So, without task_lock(), we cannot trust get_vma_policy() because we cannot | ||
108 | * gurantee the task never exits under us. But taking task_lock() around | ||
109 | * get_vma_plicy() causes lock order problem. | ||
110 | * | ||
111 | * To access task->mempolicy without lock, we hold a reference count of an | ||
112 | * object pointed by task->mempolicy and remember it. This will guarantee | ||
113 | * that task->mempolicy points to an alive object or NULL in numa_maps accesses. | ||
114 | */ | ||
115 | static void hold_task_mempolicy(struct proc_maps_private *priv) | ||
116 | { | ||
117 | struct task_struct *task = priv->task; | ||
118 | |||
119 | task_lock(task); | ||
120 | priv->task_mempolicy = task->mempolicy; | ||
121 | mpol_get(priv->task_mempolicy); | ||
122 | task_unlock(task); | ||
123 | } | ||
124 | static void release_task_mempolicy(struct proc_maps_private *priv) | ||
125 | { | ||
126 | mpol_put(priv->task_mempolicy); | ||
127 | } | ||
128 | #else | ||
129 | static void hold_task_mempolicy(struct proc_maps_private *priv) | ||
130 | { | ||
131 | } | ||
132 | static void release_task_mempolicy(struct proc_maps_private *priv) | ||
133 | { | ||
134 | } | ||
135 | #endif | ||
136 | |||
93 | static void vma_stop(struct proc_maps_private *priv, struct vm_area_struct *vma) | 137 | static void vma_stop(struct proc_maps_private *priv, struct vm_area_struct *vma) |
94 | { | 138 | { |
95 | if (vma && vma != priv->tail_vma) { | 139 | if (vma && vma != priv->tail_vma) { |
96 | struct mm_struct *mm = vma->vm_mm; | 140 | struct mm_struct *mm = vma->vm_mm; |
141 | release_task_mempolicy(priv); | ||
97 | up_read(&mm->mmap_sem); | 142 | up_read(&mm->mmap_sem); |
98 | mmput(mm); | 143 | mmput(mm); |
99 | } | 144 | } |
@@ -132,7 +177,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) | |||
132 | 177 | ||
133 | tail_vma = get_gate_vma(priv->task->mm); | 178 | tail_vma = get_gate_vma(priv->task->mm); |
134 | priv->tail_vma = tail_vma; | 179 | priv->tail_vma = tail_vma; |
135 | 180 | hold_task_mempolicy(priv); | |
136 | /* Start with last addr hint */ | 181 | /* Start with last addr hint */ |
137 | vma = find_vma(mm, last_addr); | 182 | vma = find_vma(mm, last_addr); |
138 | if (last_addr && vma) { | 183 | if (last_addr && vma) { |
@@ -159,6 +204,7 @@ out: | |||
159 | if (vma) | 204 | if (vma) |
160 | return vma; | 205 | return vma; |
161 | 206 | ||
207 | release_task_mempolicy(priv); | ||
162 | /* End of vmas has been reached */ | 208 | /* End of vmas has been reached */ |
163 | m->version = (tail_vma != NULL)? 0: -1UL; | 209 | m->version = (tail_vma != NULL)? 0: -1UL; |
164 | up_read(&mm->mmap_sem); | 210 | up_read(&mm->mmap_sem); |
@@ -1158,6 +1204,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) | |||
1158 | struct vm_area_struct *vma = v; | 1204 | struct vm_area_struct *vma = v; |
1159 | struct numa_maps *md = &numa_priv->md; | 1205 | struct numa_maps *md = &numa_priv->md; |
1160 | struct file *file = vma->vm_file; | 1206 | struct file *file = vma->vm_file; |
1207 | struct task_struct *task = proc_priv->task; | ||
1161 | struct mm_struct *mm = vma->vm_mm; | 1208 | struct mm_struct *mm = vma->vm_mm; |
1162 | struct mm_walk walk = {}; | 1209 | struct mm_walk walk = {}; |
1163 | struct mempolicy *pol; | 1210 | struct mempolicy *pol; |
@@ -1177,7 +1224,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) | |||
1177 | walk.private = md; | 1224 | walk.private = md; |
1178 | walk.mm = mm; | 1225 | walk.mm = mm; |
1179 | 1226 | ||
1180 | pol = get_vma_policy(proc_priv->task, vma, vma->vm_start); | 1227 | pol = get_vma_policy(task, vma, vma->vm_start); |
1181 | mpol_to_str(buffer, sizeof(buffer), pol, 0); | 1228 | mpol_to_str(buffer, sizeof(buffer), pol, 0); |
1182 | mpol_cond_put(pol); | 1229 | mpol_cond_put(pol); |
1183 | 1230 | ||
@@ -1189,7 +1236,7 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) | |||
1189 | } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { | 1236 | } else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { |
1190 | seq_printf(m, " heap"); | 1237 | seq_printf(m, " heap"); |
1191 | } else { | 1238 | } else { |
1192 | pid_t tid = vm_is_stack(proc_priv->task, vma, is_pid); | 1239 | pid_t tid = vm_is_stack(task, vma, is_pid); |
1193 | if (tid != 0) { | 1240 | if (tid != 0) { |
1194 | /* | 1241 | /* |
1195 | * Thread stack in /proc/PID/task/TID/maps or | 1242 | * Thread stack in /proc/PID/task/TID/maps or |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 557a9c20a215..05ae3c97f7a5 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -1160,6 +1160,8 @@ static int need_print_warning(struct dquot_warn *warn) | |||
1160 | return uid_eq(current_fsuid(), warn->w_dq_id.uid); | 1160 | return uid_eq(current_fsuid(), warn->w_dq_id.uid); |
1161 | case GRPQUOTA: | 1161 | case GRPQUOTA: |
1162 | return in_group_p(warn->w_dq_id.gid); | 1162 | return in_group_p(warn->w_dq_id.gid); |
1163 | case PRJQUOTA: /* Never taken... Just make gcc happy */ | ||
1164 | return 0; | ||
1163 | } | 1165 | } |
1164 | return 0; | 1166 | return 0; |
1165 | } | 1167 | } |
diff --git a/fs/xattr.c b/fs/xattr.c index e164dddb8e96..e21c119f4f99 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -846,7 +846,7 @@ static int __simple_xattr_set(struct simple_xattrs *xattrs, const char *name, | |||
846 | const void *value, size_t size, int flags) | 846 | const void *value, size_t size, int flags) |
847 | { | 847 | { |
848 | struct simple_xattr *xattr; | 848 | struct simple_xattr *xattr; |
849 | struct simple_xattr *uninitialized_var(new_xattr); | 849 | struct simple_xattr *new_xattr = NULL; |
850 | int err = 0; | 850 | int err = 0; |
851 | 851 | ||
852 | /* value == NULL means remove */ | 852 | /* value == NULL means remove */ |