aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/coredump.c5
-rw-r--r--fs/devpts/inode.c61
-rw-r--r--fs/ext2/super.c4
-rw-r--r--fs/ext3/namei.c40
-rw-r--r--fs/ext3/namei.h19
-rw-r--r--fs/ext3/super.c4
-rw-r--r--fs/lockd/clntxdr.c2
-rw-r--r--fs/lockd/svcproc.c3
-rw-r--r--fs/proc/internal.h4
-rw-r--r--fs/proc/task_mmu.c53
-rw-r--r--fs/quota/dquot.c2
-rw-r--r--fs/xattr.c2
12 files changed, 143 insertions, 56 deletions
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
460void do_coredump(siginfo_t *siginfo, struct pt_regs *regs) 461void do_coredump(siginfo_t *siginfo, struct pt_regs *regs)
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 14afbabe6546..472e6befc54d 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -545,37 +545,38 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx)
545 mutex_unlock(&allocated_ptys_lock); 545 mutex_unlock(&allocated_ptys_lock);
546} 546}
547 547
548int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) 548/**
549 * devpts_pty_new -- create a new inode in /dev/pts/
550 * @ptmx_inode: inode of the master
551 * @device: major+minor of the node to be created
552 * @index: used as a name of the node
553 * @priv: what's given back by devpts_get_priv
554 *
555 * The created inode is returned. Remove it from /dev/pts/ by devpts_pty_kill.
556 */
557struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
558 void *priv)
549{ 559{
550 /* tty layer puts index from devpts_new_index() in here */
551 int number = tty->index;
552 struct tty_driver *driver = tty->driver;
553 dev_t device = MKDEV(driver->major, driver->minor_start+number);
554 struct dentry *dentry; 560 struct dentry *dentry;
555 struct super_block *sb = pts_sb_from_inode(ptmx_inode); 561 struct super_block *sb = pts_sb_from_inode(ptmx_inode);
556 struct inode *inode = new_inode(sb); 562 struct inode *inode;
557 struct dentry *root = sb->s_root; 563 struct dentry *root = sb->s_root;
558 struct pts_fs_info *fsi = DEVPTS_SB(sb); 564 struct pts_fs_info *fsi = DEVPTS_SB(sb);
559 struct pts_mount_opts *opts = &fsi->mount_opts; 565 struct pts_mount_opts *opts = &fsi->mount_opts;
560 int ret = 0;
561 char s[12]; 566 char s[12];
562 567
563 /* We're supposed to be given the slave end of a pty */ 568 inode = new_inode(sb);
564 BUG_ON(driver->type != TTY_DRIVER_TYPE_PTY);
565 BUG_ON(driver->subtype != PTY_TYPE_SLAVE);
566
567 if (!inode) 569 if (!inode)
568 return -ENOMEM; 570 return ERR_PTR(-ENOMEM);
569 571
570 inode->i_ino = number + 3; 572 inode->i_ino = index + 3;
571 inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); 573 inode->i_uid = opts->setuid ? opts->uid : current_fsuid();
572 inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); 574 inode->i_gid = opts->setgid ? opts->gid : current_fsgid();
573 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 575 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
574 init_special_inode(inode, S_IFCHR|opts->mode, device); 576 init_special_inode(inode, S_IFCHR|opts->mode, device);
575 inode->i_private = tty; 577 inode->i_private = priv;
576 tty->driver_data = inode;
577 578
578 sprintf(s, "%d", number); 579 sprintf(s, "%d", index);
579 580
580 mutex_lock(&root->d_inode->i_mutex); 581 mutex_lock(&root->d_inode->i_mutex);
581 582
@@ -585,18 +586,24 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
585 fsnotify_create(root->d_inode, dentry); 586 fsnotify_create(root->d_inode, dentry);
586 } else { 587 } else {
587 iput(inode); 588 iput(inode);
588 ret = -ENOMEM; 589 inode = ERR_PTR(-ENOMEM);
589 } 590 }
590 591
591 mutex_unlock(&root->d_inode->i_mutex); 592 mutex_unlock(&root->d_inode->i_mutex);
592 593
593 return ret; 594 return inode;
594} 595}
595 596
596struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number) 597/**
598 * devpts_get_priv -- get private data for a slave
599 * @pts_inode: inode of the slave
600 *
601 * Returns whatever was passed as priv in devpts_pty_new for a given inode.
602 */
603void *devpts_get_priv(struct inode *pts_inode)
597{ 604{
598 struct dentry *dentry; 605 struct dentry *dentry;
599 struct tty_struct *tty; 606 void *priv = NULL;
600 607
601 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR)); 608 BUG_ON(pts_inode->i_rdev == MKDEV(TTYAUX_MAJOR, PTMX_MINOR));
602 609
@@ -605,18 +612,22 @@ struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number)
605 if (!dentry) 612 if (!dentry)
606 return NULL; 613 return NULL;
607 614
608 tty = NULL;
609 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC) 615 if (pts_inode->i_sb->s_magic == DEVPTS_SUPER_MAGIC)
610 tty = (struct tty_struct *)pts_inode->i_private; 616 priv = pts_inode->i_private;
611 617
612 dput(dentry); 618 dput(dentry);
613 619
614 return tty; 620 return priv;
615} 621}
616 622
617void devpts_pty_kill(struct tty_struct *tty) 623/**
624 * devpts_pty_kill -- remove inode form /dev/pts/
625 * @inode: inode of the slave to be removed
626 *
627 * This is an inverse operation of devpts_pty_new.
628 */
629void devpts_pty_kill(struct inode *inode)
618{ 630{
619 struct inode *inode = tty->driver_data;
620 struct super_block *sb = pts_sb_from_inode(inode); 631 struct super_block *sb = pts_sb_from_inode(inode);
621 struct dentry *root = sb->s_root; 632 struct dentry *root = sb->s_root;
622 struct dentry *dentry; 633 struct dentry *dentry;
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
8extern struct dentry *ext3_get_parent(struct dentry *child); 8extern struct dentry *ext3_get_parent(struct dentry *child);
9
10static 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>
14struct ctl_table_header; 14struct ctl_table_header;
15struct mempolicy;
15 16
16extern struct proc_dir_entry proc_root; 17extern 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
79void proc_init_inodecache(void); 83void 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 */
115static 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}
124static void release_task_mempolicy(struct proc_maps_private *priv)
125{
126 mpol_put(priv->task_mempolicy);
127}
128#else
129static void hold_task_mempolicy(struct proc_maps_private *priv)
130{
131}
132static void release_task_mempolicy(struct proc_maps_private *priv)
133{
134}
135#endif
136
93static void vma_stop(struct proc_maps_private *priv, struct vm_area_struct *vma) 137static 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 */