diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 19:07:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-02 19:07:27 -0400 |
commit | 092f4c56c1927e4b61a41ee8055005f1cb437009 (patch) | |
tree | 616ceb54b7671ccc13922ae9e002b8b972f6e09e /fs | |
parent | 80c2861672bbf000f6af838656959ee937e4ee4d (diff) | |
parent | c1e2ee2dc436574880758b3836fc96935b774c32 (diff) |
Merge branch 'akpm' (Andrew's incoming - part two)
Says Andrew:
"60 patches. That's good enough for -rc1 I guess. I have quite a lot
of detritus to be rechecked, work through maintainers, etc.
- most of the remains of MM
- rtc
- various misc
- cgroups
- memcg
- cpusets
- procfs
- ipc
- rapidio
- sysctl
- pps
- w1
- drivers/misc
- aio"
* akpm: (60 commits)
memcg: replace ss->id_lock with a rwlock
aio: allocate kiocbs in batches
drivers/misc/vmw_balloon.c: fix typo in code comment
drivers/misc/vmw_balloon.c: determine page allocation flag can_sleep outside loop
w1: disable irqs in critical section
drivers/w1/w1_int.c: multiple masters used same init_name
drivers/power/ds2780_battery.c: fix deadlock upon insertion and removal
drivers/power/ds2780_battery.c: add a nolock function to w1 interface
drivers/power/ds2780_battery.c: create central point for calling w1 interface
w1: ds2760 and ds2780, use ida for id and ida_simple_get() to get it
pps gpio client: add missing dependency
pps: new client driver using GPIO
pps: default echo function
include/linux/dma-mapping.h: add dma_zalloc_coherent()
sysctl: make CONFIG_SYSCTL_SYSCALL default to n
sysctl: add support for poll()
RapidIO: documentation update
drivers/net/rionet.c: fix ethernet address macros for LE platforms
RapidIO: fix potential null deref in rio_setup_device()
RapidIO: add mport driver for Tsi721 bridge
...
Diffstat (limited to 'fs')
-rw-r--r-- | fs/aio.c | 136 | ||||
-rw-r--r-- | fs/binfmt_elf.c | 11 | ||||
-rw-r--r-- | fs/hfs/btree.c | 20 | ||||
-rw-r--r-- | fs/isofs/inode.c | 10 | ||||
-rw-r--r-- | fs/proc/base.c | 146 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 46 | ||||
-rw-r--r-- | fs/ramfs/inode.c | 10 |
7 files changed, 290 insertions, 89 deletions
@@ -440,8 +440,6 @@ void exit_aio(struct mm_struct *mm) | |||
440 | static struct kiocb *__aio_get_req(struct kioctx *ctx) | 440 | static struct kiocb *__aio_get_req(struct kioctx *ctx) |
441 | { | 441 | { |
442 | struct kiocb *req = NULL; | 442 | struct kiocb *req = NULL; |
443 | struct aio_ring *ring; | ||
444 | int okay = 0; | ||
445 | 443 | ||
446 | req = kmem_cache_alloc(kiocb_cachep, GFP_KERNEL); | 444 | req = kmem_cache_alloc(kiocb_cachep, GFP_KERNEL); |
447 | if (unlikely(!req)) | 445 | if (unlikely(!req)) |
@@ -459,39 +457,114 @@ static struct kiocb *__aio_get_req(struct kioctx *ctx) | |||
459 | INIT_LIST_HEAD(&req->ki_run_list); | 457 | INIT_LIST_HEAD(&req->ki_run_list); |
460 | req->ki_eventfd = NULL; | 458 | req->ki_eventfd = NULL; |
461 | 459 | ||
462 | /* Check if the completion queue has enough free space to | 460 | return req; |
463 | * accept an event from this io. | 461 | } |
464 | */ | 462 | |
463 | /* | ||
464 | * struct kiocb's are allocated in batches to reduce the number of | ||
465 | * times the ctx lock is acquired and released. | ||
466 | */ | ||
467 | #define KIOCB_BATCH_SIZE 32L | ||
468 | struct kiocb_batch { | ||
469 | struct list_head head; | ||
470 | long count; /* number of requests left to allocate */ | ||
471 | }; | ||
472 | |||
473 | static void kiocb_batch_init(struct kiocb_batch *batch, long total) | ||
474 | { | ||
475 | INIT_LIST_HEAD(&batch->head); | ||
476 | batch->count = total; | ||
477 | } | ||
478 | |||
479 | static void kiocb_batch_free(struct kiocb_batch *batch) | ||
480 | { | ||
481 | struct kiocb *req, *n; | ||
482 | |||
483 | list_for_each_entry_safe(req, n, &batch->head, ki_batch) { | ||
484 | list_del(&req->ki_batch); | ||
485 | kmem_cache_free(kiocb_cachep, req); | ||
486 | } | ||
487 | } | ||
488 | |||
489 | /* | ||
490 | * Allocate a batch of kiocbs. This avoids taking and dropping the | ||
491 | * context lock a lot during setup. | ||
492 | */ | ||
493 | static int kiocb_batch_refill(struct kioctx *ctx, struct kiocb_batch *batch) | ||
494 | { | ||
495 | unsigned short allocated, to_alloc; | ||
496 | long avail; | ||
497 | bool called_fput = false; | ||
498 | struct kiocb *req, *n; | ||
499 | struct aio_ring *ring; | ||
500 | |||
501 | to_alloc = min(batch->count, KIOCB_BATCH_SIZE); | ||
502 | for (allocated = 0; allocated < to_alloc; allocated++) { | ||
503 | req = __aio_get_req(ctx); | ||
504 | if (!req) | ||
505 | /* allocation failed, go with what we've got */ | ||
506 | break; | ||
507 | list_add(&req->ki_batch, &batch->head); | ||
508 | } | ||
509 | |||
510 | if (allocated == 0) | ||
511 | goto out; | ||
512 | |||
513 | retry: | ||
465 | spin_lock_irq(&ctx->ctx_lock); | 514 | spin_lock_irq(&ctx->ctx_lock); |
466 | ring = kmap_atomic(ctx->ring_info.ring_pages[0], KM_USER0); | 515 | ring = kmap_atomic(ctx->ring_info.ring_pages[0]); |
467 | if (ctx->reqs_active < aio_ring_avail(&ctx->ring_info, ring)) { | 516 | |
517 | avail = aio_ring_avail(&ctx->ring_info, ring) - ctx->reqs_active; | ||
518 | BUG_ON(avail < 0); | ||
519 | if (avail == 0 && !called_fput) { | ||
520 | /* | ||
521 | * Handle a potential starvation case. It is possible that | ||
522 | * we hold the last reference on a struct file, causing us | ||
523 | * to delay the final fput to non-irq context. In this case, | ||
524 | * ctx->reqs_active is artificially high. Calling the fput | ||
525 | * routine here may free up a slot in the event completion | ||
526 | * ring, allowing this allocation to succeed. | ||
527 | */ | ||
528 | kunmap_atomic(ring); | ||
529 | spin_unlock_irq(&ctx->ctx_lock); | ||
530 | aio_fput_routine(NULL); | ||
531 | called_fput = true; | ||
532 | goto retry; | ||
533 | } | ||
534 | |||
535 | if (avail < allocated) { | ||
536 | /* Trim back the number of requests. */ | ||
537 | list_for_each_entry_safe(req, n, &batch->head, ki_batch) { | ||
538 | list_del(&req->ki_batch); | ||
539 | kmem_cache_free(kiocb_cachep, req); | ||
540 | if (--allocated <= avail) | ||
541 | break; | ||
542 | } | ||
543 | } | ||
544 | |||
545 | batch->count -= allocated; | ||
546 | list_for_each_entry(req, &batch->head, ki_batch) { | ||
468 | list_add(&req->ki_list, &ctx->active_reqs); | 547 | list_add(&req->ki_list, &ctx->active_reqs); |
469 | ctx->reqs_active++; | 548 | ctx->reqs_active++; |
470 | okay = 1; | ||
471 | } | 549 | } |
472 | kunmap_atomic(ring, KM_USER0); | ||
473 | spin_unlock_irq(&ctx->ctx_lock); | ||
474 | 550 | ||
475 | if (!okay) { | 551 | kunmap_atomic(ring); |
476 | kmem_cache_free(kiocb_cachep, req); | 552 | spin_unlock_irq(&ctx->ctx_lock); |
477 | req = NULL; | ||
478 | } | ||
479 | 553 | ||
480 | return req; | 554 | out: |
555 | return allocated; | ||
481 | } | 556 | } |
482 | 557 | ||
483 | static inline struct kiocb *aio_get_req(struct kioctx *ctx) | 558 | static inline struct kiocb *aio_get_req(struct kioctx *ctx, |
559 | struct kiocb_batch *batch) | ||
484 | { | 560 | { |
485 | struct kiocb *req; | 561 | struct kiocb *req; |
486 | /* Handle a potential starvation case -- should be exceedingly rare as | 562 | |
487 | * requests will be stuck on fput_head only if the aio_fput_routine is | 563 | if (list_empty(&batch->head)) |
488 | * delayed and the requests were the last user of the struct file. | 564 | if (kiocb_batch_refill(ctx, batch) == 0) |
489 | */ | 565 | return NULL; |
490 | req = __aio_get_req(ctx); | 566 | req = list_first_entry(&batch->head, struct kiocb, ki_batch); |
491 | if (unlikely(NULL == req)) { | 567 | list_del(&req->ki_batch); |
492 | aio_fput_routine(NULL); | ||
493 | req = __aio_get_req(ctx); | ||
494 | } | ||
495 | return req; | 568 | return req; |
496 | } | 569 | } |
497 | 570 | ||
@@ -1515,7 +1588,8 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat) | |||
1515 | } | 1588 | } |
1516 | 1589 | ||
1517 | static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | 1590 | static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, |
1518 | struct iocb *iocb, bool compat) | 1591 | struct iocb *iocb, struct kiocb_batch *batch, |
1592 | bool compat) | ||
1519 | { | 1593 | { |
1520 | struct kiocb *req; | 1594 | struct kiocb *req; |
1521 | struct file *file; | 1595 | struct file *file; |
@@ -1541,7 +1615,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1541 | if (unlikely(!file)) | 1615 | if (unlikely(!file)) |
1542 | return -EBADF; | 1616 | return -EBADF; |
1543 | 1617 | ||
1544 | req = aio_get_req(ctx); /* returns with 2 references to req */ | 1618 | req = aio_get_req(ctx, batch); /* returns with 2 references to req */ |
1545 | if (unlikely(!req)) { | 1619 | if (unlikely(!req)) { |
1546 | fput(file); | 1620 | fput(file); |
1547 | return -EAGAIN; | 1621 | return -EAGAIN; |
@@ -1621,8 +1695,9 @@ long do_io_submit(aio_context_t ctx_id, long nr, | |||
1621 | { | 1695 | { |
1622 | struct kioctx *ctx; | 1696 | struct kioctx *ctx; |
1623 | long ret = 0; | 1697 | long ret = 0; |
1624 | int i; | 1698 | int i = 0; |
1625 | struct blk_plug plug; | 1699 | struct blk_plug plug; |
1700 | struct kiocb_batch batch; | ||
1626 | 1701 | ||
1627 | if (unlikely(nr < 0)) | 1702 | if (unlikely(nr < 0)) |
1628 | return -EINVAL; | 1703 | return -EINVAL; |
@@ -1639,6 +1714,8 @@ long do_io_submit(aio_context_t ctx_id, long nr, | |||
1639 | return -EINVAL; | 1714 | return -EINVAL; |
1640 | } | 1715 | } |
1641 | 1716 | ||
1717 | kiocb_batch_init(&batch, nr); | ||
1718 | |||
1642 | blk_start_plug(&plug); | 1719 | blk_start_plug(&plug); |
1643 | 1720 | ||
1644 | /* | 1721 | /* |
@@ -1659,12 +1736,13 @@ long do_io_submit(aio_context_t ctx_id, long nr, | |||
1659 | break; | 1736 | break; |
1660 | } | 1737 | } |
1661 | 1738 | ||
1662 | ret = io_submit_one(ctx, user_iocb, &tmp, compat); | 1739 | ret = io_submit_one(ctx, user_iocb, &tmp, &batch, compat); |
1663 | if (ret) | 1740 | if (ret) |
1664 | break; | 1741 | break; |
1665 | } | 1742 | } |
1666 | blk_finish_plug(&plug); | 1743 | blk_finish_plug(&plug); |
1667 | 1744 | ||
1745 | kiocb_batch_free(&batch); | ||
1668 | put_ioctx(ctx); | 1746 | put_ioctx(ctx); |
1669 | return i ? i : ret; | 1747 | return i ? i : ret; |
1670 | } | 1748 | } |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index dd0fdfc56d38..21ac5ee4b43f 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -795,7 +795,16 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
795 | * might try to exec. This is because the brk will | 795 | * might try to exec. This is because the brk will |
796 | * follow the loader, and is not movable. */ | 796 | * follow the loader, and is not movable. */ |
797 | #if defined(CONFIG_X86) || defined(CONFIG_ARM) | 797 | #if defined(CONFIG_X86) || defined(CONFIG_ARM) |
798 | load_bias = 0; | 798 | /* Memory randomization might have been switched off |
799 | * in runtime via sysctl. | ||
800 | * If that is the case, retain the original non-zero | ||
801 | * load_bias value in order to establish proper | ||
802 | * non-randomized mappings. | ||
803 | */ | ||
804 | if (current->flags & PF_RANDOMIZE) | ||
805 | load_bias = 0; | ||
806 | else | ||
807 | load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); | ||
799 | #else | 808 | #else |
800 | load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); | 809 | load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); |
801 | #endif | 810 | #endif |
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 3ebc437736fe..1cbdeea1db44 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c | |||
@@ -46,11 +46,26 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
46 | case HFS_EXT_CNID: | 46 | case HFS_EXT_CNID: |
47 | hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize, | 47 | hfs_inode_read_fork(tree->inode, mdb->drXTExtRec, mdb->drXTFlSize, |
48 | mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); | 48 | mdb->drXTFlSize, be32_to_cpu(mdb->drXTClpSiz)); |
49 | if (HFS_I(tree->inode)->alloc_blocks > | ||
50 | HFS_I(tree->inode)->first_blocks) { | ||
51 | printk(KERN_ERR "hfs: invalid btree extent records\n"); | ||
52 | unlock_new_inode(tree->inode); | ||
53 | goto free_inode; | ||
54 | } | ||
55 | |||
49 | tree->inode->i_mapping->a_ops = &hfs_btree_aops; | 56 | tree->inode->i_mapping->a_ops = &hfs_btree_aops; |
50 | break; | 57 | break; |
51 | case HFS_CAT_CNID: | 58 | case HFS_CAT_CNID: |
52 | hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize, | 59 | hfs_inode_read_fork(tree->inode, mdb->drCTExtRec, mdb->drCTFlSize, |
53 | mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); | 60 | mdb->drCTFlSize, be32_to_cpu(mdb->drCTClpSiz)); |
61 | |||
62 | if (!HFS_I(tree->inode)->first_blocks) { | ||
63 | printk(KERN_ERR "hfs: invalid btree extent records " | ||
64 | "(0 size).\n"); | ||
65 | unlock_new_inode(tree->inode); | ||
66 | goto free_inode; | ||
67 | } | ||
68 | |||
54 | tree->inode->i_mapping->a_ops = &hfs_btree_aops; | 69 | tree->inode->i_mapping->a_ops = &hfs_btree_aops; |
55 | break; | 70 | break; |
56 | default: | 71 | default: |
@@ -59,11 +74,6 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
59 | } | 74 | } |
60 | unlock_new_inode(tree->inode); | 75 | unlock_new_inode(tree->inode); |
61 | 76 | ||
62 | if (!HFS_I(tree->inode)->first_blocks) { | ||
63 | printk(KERN_ERR "hfs: invalid btree extent records (0 size).\n"); | ||
64 | goto free_inode; | ||
65 | } | ||
66 | |||
67 | mapping = tree->inode->i_mapping; | 77 | mapping = tree->inode->i_mapping; |
68 | page = read_mapping_page(mapping, 0, NULL); | 78 | page = read_mapping_page(mapping, 0, NULL); |
69 | if (IS_ERR(page)) | 79 | if (IS_ERR(page)) |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 562adabef985..f950059525fc 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/statfs.h> | 20 | #include <linux/statfs.h> |
21 | #include <linux/cdrom.h> | 21 | #include <linux/cdrom.h> |
22 | #include <linux/parser.h> | 22 | #include <linux/parser.h> |
23 | #include <linux/mpage.h> | ||
23 | 24 | ||
24 | #include "isofs.h" | 25 | #include "isofs.h" |
25 | #include "zisofs.h" | 26 | #include "zisofs.h" |
@@ -1148,7 +1149,13 @@ struct buffer_head *isofs_bread(struct inode *inode, sector_t block) | |||
1148 | 1149 | ||
1149 | static int isofs_readpage(struct file *file, struct page *page) | 1150 | static int isofs_readpage(struct file *file, struct page *page) |
1150 | { | 1151 | { |
1151 | return block_read_full_page(page,isofs_get_block); | 1152 | return mpage_readpage(page, isofs_get_block); |
1153 | } | ||
1154 | |||
1155 | static int isofs_readpages(struct file *file, struct address_space *mapping, | ||
1156 | struct list_head *pages, unsigned nr_pages) | ||
1157 | { | ||
1158 | return mpage_readpages(mapping, pages, nr_pages, isofs_get_block); | ||
1152 | } | 1159 | } |
1153 | 1160 | ||
1154 | static sector_t _isofs_bmap(struct address_space *mapping, sector_t block) | 1161 | static sector_t _isofs_bmap(struct address_space *mapping, sector_t block) |
@@ -1158,6 +1165,7 @@ static sector_t _isofs_bmap(struct address_space *mapping, sector_t block) | |||
1158 | 1165 | ||
1159 | static const struct address_space_operations isofs_aops = { | 1166 | static const struct address_space_operations isofs_aops = { |
1160 | .readpage = isofs_readpage, | 1167 | .readpage = isofs_readpage, |
1168 | .readpages = isofs_readpages, | ||
1161 | .bmap = _isofs_bmap | 1169 | .bmap = _isofs_bmap |
1162 | }; | 1170 | }; |
1163 | 1171 | ||
diff --git a/fs/proc/base.c b/fs/proc/base.c index 851ba3dcdc29..2db1bd3173b2 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1652,12 +1652,46 @@ out: | |||
1652 | return error; | 1652 | return error; |
1653 | } | 1653 | } |
1654 | 1654 | ||
1655 | static int proc_pid_fd_link_getattr(struct vfsmount *mnt, struct dentry *dentry, | ||
1656 | struct kstat *stat) | ||
1657 | { | ||
1658 | struct inode *inode = dentry->d_inode; | ||
1659 | struct task_struct *task = get_proc_task(inode); | ||
1660 | int rc; | ||
1661 | |||
1662 | if (task == NULL) | ||
1663 | return -ESRCH; | ||
1664 | |||
1665 | rc = -EACCES; | ||
1666 | if (lock_trace(task)) | ||
1667 | goto out_task; | ||
1668 | |||
1669 | generic_fillattr(inode, stat); | ||
1670 | unlock_trace(task); | ||
1671 | rc = 0; | ||
1672 | out_task: | ||
1673 | put_task_struct(task); | ||
1674 | return rc; | ||
1675 | } | ||
1676 | |||
1655 | static const struct inode_operations proc_pid_link_inode_operations = { | 1677 | static const struct inode_operations proc_pid_link_inode_operations = { |
1656 | .readlink = proc_pid_readlink, | 1678 | .readlink = proc_pid_readlink, |
1657 | .follow_link = proc_pid_follow_link, | 1679 | .follow_link = proc_pid_follow_link, |
1658 | .setattr = proc_setattr, | 1680 | .setattr = proc_setattr, |
1659 | }; | 1681 | }; |
1660 | 1682 | ||
1683 | static const struct inode_operations proc_fdinfo_link_inode_operations = { | ||
1684 | .setattr = proc_setattr, | ||
1685 | .getattr = proc_pid_fd_link_getattr, | ||
1686 | }; | ||
1687 | |||
1688 | static const struct inode_operations proc_fd_link_inode_operations = { | ||
1689 | .readlink = proc_pid_readlink, | ||
1690 | .follow_link = proc_pid_follow_link, | ||
1691 | .setattr = proc_setattr, | ||
1692 | .getattr = proc_pid_fd_link_getattr, | ||
1693 | }; | ||
1694 | |||
1661 | 1695 | ||
1662 | /* building an inode */ | 1696 | /* building an inode */ |
1663 | 1697 | ||
@@ -1889,49 +1923,61 @@ out: | |||
1889 | 1923 | ||
1890 | static int proc_fd_info(struct inode *inode, struct path *path, char *info) | 1924 | static int proc_fd_info(struct inode *inode, struct path *path, char *info) |
1891 | { | 1925 | { |
1892 | struct task_struct *task = get_proc_task(inode); | 1926 | struct task_struct *task; |
1893 | struct files_struct *files = NULL; | 1927 | struct files_struct *files; |
1894 | struct file *file; | 1928 | struct file *file; |
1895 | int fd = proc_fd(inode); | 1929 | int fd = proc_fd(inode); |
1930 | int rc; | ||
1896 | 1931 | ||
1897 | if (task) { | 1932 | task = get_proc_task(inode); |
1898 | files = get_files_struct(task); | 1933 | if (!task) |
1899 | put_task_struct(task); | 1934 | return -ENOENT; |
1900 | } | 1935 | |
1901 | if (files) { | 1936 | rc = -EACCES; |
1902 | /* | 1937 | if (lock_trace(task)) |
1903 | * We are not taking a ref to the file structure, so we must | 1938 | goto out_task; |
1904 | * hold ->file_lock. | 1939 | |
1905 | */ | 1940 | rc = -ENOENT; |
1906 | spin_lock(&files->file_lock); | 1941 | files = get_files_struct(task); |
1907 | file = fcheck_files(files, fd); | 1942 | if (files == NULL) |
1908 | if (file) { | 1943 | goto out_unlock; |
1909 | unsigned int f_flags; | 1944 | |
1910 | struct fdtable *fdt; | 1945 | /* |
1911 | 1946 | * We are not taking a ref to the file structure, so we must | |
1912 | fdt = files_fdtable(files); | 1947 | * hold ->file_lock. |
1913 | f_flags = file->f_flags & ~O_CLOEXEC; | 1948 | */ |
1914 | if (FD_ISSET(fd, fdt->close_on_exec)) | 1949 | spin_lock(&files->file_lock); |
1915 | f_flags |= O_CLOEXEC; | 1950 | file = fcheck_files(files, fd); |
1916 | 1951 | if (file) { | |
1917 | if (path) { | 1952 | unsigned int f_flags; |
1918 | *path = file->f_path; | 1953 | struct fdtable *fdt; |
1919 | path_get(&file->f_path); | 1954 | |
1920 | } | 1955 | fdt = files_fdtable(files); |
1921 | if (info) | 1956 | f_flags = file->f_flags & ~O_CLOEXEC; |
1922 | snprintf(info, PROC_FDINFO_MAX, | 1957 | if (FD_ISSET(fd, fdt->close_on_exec)) |
1923 | "pos:\t%lli\n" | 1958 | f_flags |= O_CLOEXEC; |
1924 | "flags:\t0%o\n", | 1959 | |
1925 | (long long) file->f_pos, | 1960 | if (path) { |
1926 | f_flags); | 1961 | *path = file->f_path; |
1927 | spin_unlock(&files->file_lock); | 1962 | path_get(&file->f_path); |
1928 | put_files_struct(files); | ||
1929 | return 0; | ||
1930 | } | 1963 | } |
1931 | spin_unlock(&files->file_lock); | 1964 | if (info) |
1932 | put_files_struct(files); | 1965 | snprintf(info, PROC_FDINFO_MAX, |
1933 | } | 1966 | "pos:\t%lli\n" |
1934 | return -ENOENT; | 1967 | "flags:\t0%o\n", |
1968 | (long long) file->f_pos, | ||
1969 | f_flags); | ||
1970 | rc = 0; | ||
1971 | } else | ||
1972 | rc = -ENOENT; | ||
1973 | spin_unlock(&files->file_lock); | ||
1974 | put_files_struct(files); | ||
1975 | |||
1976 | out_unlock: | ||
1977 | unlock_trace(task); | ||
1978 | out_task: | ||
1979 | put_task_struct(task); | ||
1980 | return rc; | ||
1935 | } | 1981 | } |
1936 | 1982 | ||
1937 | static int proc_fd_link(struct inode *inode, struct path *path) | 1983 | static int proc_fd_link(struct inode *inode, struct path *path) |
@@ -2026,7 +2072,7 @@ static struct dentry *proc_fd_instantiate(struct inode *dir, | |||
2026 | spin_unlock(&files->file_lock); | 2072 | spin_unlock(&files->file_lock); |
2027 | put_files_struct(files); | 2073 | put_files_struct(files); |
2028 | 2074 | ||
2029 | inode->i_op = &proc_pid_link_inode_operations; | 2075 | inode->i_op = &proc_fd_link_inode_operations; |
2030 | inode->i_size = 64; | 2076 | inode->i_size = 64; |
2031 | ei->op.proc_get_link = proc_fd_link; | 2077 | ei->op.proc_get_link = proc_fd_link; |
2032 | d_set_d_op(dentry, &tid_fd_dentry_operations); | 2078 | d_set_d_op(dentry, &tid_fd_dentry_operations); |
@@ -2058,7 +2104,12 @@ static struct dentry *proc_lookupfd_common(struct inode *dir, | |||
2058 | if (fd == ~0U) | 2104 | if (fd == ~0U) |
2059 | goto out; | 2105 | goto out; |
2060 | 2106 | ||
2107 | result = ERR_PTR(-EACCES); | ||
2108 | if (lock_trace(task)) | ||
2109 | goto out; | ||
2110 | |||
2061 | result = instantiate(dir, dentry, task, &fd); | 2111 | result = instantiate(dir, dentry, task, &fd); |
2112 | unlock_trace(task); | ||
2062 | out: | 2113 | out: |
2063 | put_task_struct(task); | 2114 | put_task_struct(task); |
2064 | out_no_task: | 2115 | out_no_task: |
@@ -2078,23 +2129,28 @@ static int proc_readfd_common(struct file * filp, void * dirent, | |||
2078 | retval = -ENOENT; | 2129 | retval = -ENOENT; |
2079 | if (!p) | 2130 | if (!p) |
2080 | goto out_no_task; | 2131 | goto out_no_task; |
2132 | |||
2133 | retval = -EACCES; | ||
2134 | if (lock_trace(p)) | ||
2135 | goto out; | ||
2136 | |||
2081 | retval = 0; | 2137 | retval = 0; |
2082 | 2138 | ||
2083 | fd = filp->f_pos; | 2139 | fd = filp->f_pos; |
2084 | switch (fd) { | 2140 | switch (fd) { |
2085 | case 0: | 2141 | case 0: |
2086 | if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) | 2142 | if (filldir(dirent, ".", 1, 0, inode->i_ino, DT_DIR) < 0) |
2087 | goto out; | 2143 | goto out_unlock; |
2088 | filp->f_pos++; | 2144 | filp->f_pos++; |
2089 | case 1: | 2145 | case 1: |
2090 | ino = parent_ino(dentry); | 2146 | ino = parent_ino(dentry); |
2091 | if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) | 2147 | if (filldir(dirent, "..", 2, 1, ino, DT_DIR) < 0) |
2092 | goto out; | 2148 | goto out_unlock; |
2093 | filp->f_pos++; | 2149 | filp->f_pos++; |
2094 | default: | 2150 | default: |
2095 | files = get_files_struct(p); | 2151 | files = get_files_struct(p); |
2096 | if (!files) | 2152 | if (!files) |
2097 | goto out; | 2153 | goto out_unlock; |
2098 | rcu_read_lock(); | 2154 | rcu_read_lock(); |
2099 | for (fd = filp->f_pos-2; | 2155 | for (fd = filp->f_pos-2; |
2100 | fd < files_fdtable(files)->max_fds; | 2156 | fd < files_fdtable(files)->max_fds; |
@@ -2118,6 +2174,9 @@ static int proc_readfd_common(struct file * filp, void * dirent, | |||
2118 | rcu_read_unlock(); | 2174 | rcu_read_unlock(); |
2119 | put_files_struct(files); | 2175 | put_files_struct(files); |
2120 | } | 2176 | } |
2177 | |||
2178 | out_unlock: | ||
2179 | unlock_trace(p); | ||
2121 | out: | 2180 | out: |
2122 | put_task_struct(p); | 2181 | put_task_struct(p); |
2123 | out_no_task: | 2182 | out_no_task: |
@@ -2195,6 +2254,7 @@ static struct dentry *proc_fdinfo_instantiate(struct inode *dir, | |||
2195 | ei->fd = fd; | 2254 | ei->fd = fd; |
2196 | inode->i_mode = S_IFREG | S_IRUSR; | 2255 | inode->i_mode = S_IFREG | S_IRUSR; |
2197 | inode->i_fop = &proc_fdinfo_file_operations; | 2256 | inode->i_fop = &proc_fdinfo_file_operations; |
2257 | inode->i_op = &proc_fdinfo_link_inode_operations; | ||
2198 | d_set_d_op(dentry, &tid_fd_dentry_operations); | 2258 | d_set_d_op(dentry, &tid_fd_dentry_operations); |
2199 | d_add(dentry, inode); | 2259 | d_add(dentry, inode); |
2200 | /* Close the race of the process dying before we return the dentry */ | 2260 | /* Close the race of the process dying before we return the dentry */ |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index b44113279e30..a6b62173d4c3 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
5 | #include <linux/sysctl.h> | 5 | #include <linux/sysctl.h> |
6 | #include <linux/poll.h> | ||
6 | #include <linux/proc_fs.h> | 7 | #include <linux/proc_fs.h> |
7 | #include <linux/security.h> | 8 | #include <linux/security.h> |
8 | #include <linux/namei.h> | 9 | #include <linux/namei.h> |
@@ -14,6 +15,15 @@ static const struct inode_operations proc_sys_inode_operations; | |||
14 | static const struct file_operations proc_sys_dir_file_operations; | 15 | static const struct file_operations proc_sys_dir_file_operations; |
15 | static const struct inode_operations proc_sys_dir_operations; | 16 | static const struct inode_operations proc_sys_dir_operations; |
16 | 17 | ||
18 | void proc_sys_poll_notify(struct ctl_table_poll *poll) | ||
19 | { | ||
20 | if (!poll) | ||
21 | return; | ||
22 | |||
23 | atomic_inc(&poll->event); | ||
24 | wake_up_interruptible(&poll->wait); | ||
25 | } | ||
26 | |||
17 | static struct inode *proc_sys_make_inode(struct super_block *sb, | 27 | static struct inode *proc_sys_make_inode(struct super_block *sb, |
18 | struct ctl_table_header *head, struct ctl_table *table) | 28 | struct ctl_table_header *head, struct ctl_table *table) |
19 | { | 29 | { |
@@ -176,6 +186,39 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf, | |||
176 | return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 1); | 186 | return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 1); |
177 | } | 187 | } |
178 | 188 | ||
189 | static int proc_sys_open(struct inode *inode, struct file *filp) | ||
190 | { | ||
191 | struct ctl_table *table = PROC_I(inode)->sysctl_entry; | ||
192 | |||
193 | if (table->poll) | ||
194 | filp->private_data = proc_sys_poll_event(table->poll); | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static unsigned int proc_sys_poll(struct file *filp, poll_table *wait) | ||
200 | { | ||
201 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
202 | struct ctl_table *table = PROC_I(inode)->sysctl_entry; | ||
203 | unsigned long event = (unsigned long)filp->private_data; | ||
204 | unsigned int ret = DEFAULT_POLLMASK; | ||
205 | |||
206 | if (!table->proc_handler) | ||
207 | goto out; | ||
208 | |||
209 | if (!table->poll) | ||
210 | goto out; | ||
211 | |||
212 | poll_wait(filp, &table->poll->wait, wait); | ||
213 | |||
214 | if (event != atomic_read(&table->poll->event)) { | ||
215 | filp->private_data = proc_sys_poll_event(table->poll); | ||
216 | ret = POLLIN | POLLRDNORM | POLLERR | POLLPRI; | ||
217 | } | ||
218 | |||
219 | out: | ||
220 | return ret; | ||
221 | } | ||
179 | 222 | ||
180 | static int proc_sys_fill_cache(struct file *filp, void *dirent, | 223 | static int proc_sys_fill_cache(struct file *filp, void *dirent, |
181 | filldir_t filldir, | 224 | filldir_t filldir, |
@@ -364,12 +407,15 @@ static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct | |||
364 | } | 407 | } |
365 | 408 | ||
366 | static const struct file_operations proc_sys_file_operations = { | 409 | static const struct file_operations proc_sys_file_operations = { |
410 | .open = proc_sys_open, | ||
411 | .poll = proc_sys_poll, | ||
367 | .read = proc_sys_read, | 412 | .read = proc_sys_read, |
368 | .write = proc_sys_write, | 413 | .write = proc_sys_write, |
369 | .llseek = default_llseek, | 414 | .llseek = default_llseek, |
370 | }; | 415 | }; |
371 | 416 | ||
372 | static const struct file_operations proc_sys_dir_file_operations = { | 417 | static const struct file_operations proc_sys_dir_file_operations = { |
418 | .read = generic_read_dir, | ||
373 | .readdir = proc_sys_readdir, | 419 | .readdir = proc_sys_readdir, |
374 | .llseek = generic_file_llseek, | 420 | .llseek = generic_file_llseek, |
375 | }; | 421 | }; |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index eacb166fb259..462ceb38fec6 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -23,7 +23,6 @@ | |||
23 | * caches is sufficient. | 23 | * caches is sufficient. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
28 | #include <linux/pagemap.h> | 27 | #include <linux/pagemap.h> |
29 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
@@ -288,14 +287,7 @@ static int __init init_ramfs_fs(void) | |||
288 | { | 287 | { |
289 | return register_filesystem(&ramfs_fs_type); | 288 | return register_filesystem(&ramfs_fs_type); |
290 | } | 289 | } |
291 | |||
292 | static void __exit exit_ramfs_fs(void) | ||
293 | { | ||
294 | unregister_filesystem(&ramfs_fs_type); | ||
295 | } | ||
296 | |||
297 | module_init(init_ramfs_fs) | 290 | module_init(init_ramfs_fs) |
298 | module_exit(exit_ramfs_fs) | ||
299 | 291 | ||
300 | int __init init_rootfs(void) | 292 | int __init init_rootfs(void) |
301 | { | 293 | { |
@@ -311,5 +303,3 @@ int __init init_rootfs(void) | |||
311 | 303 | ||
312 | return err; | 304 | return err; |
313 | } | 305 | } |
314 | |||
315 | MODULE_LICENSE("GPL"); | ||