diff options
Diffstat (limited to 'fs')
79 files changed, 1842 insertions, 956 deletions
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 853845abcca6..55e8ee1900a5 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt | |||
@@ -41,7 +41,7 @@ config BINFMT_ELF_FDPIC | |||
41 | It is also possible to run FDPIC ELF binaries on MMU linux also. | 41 | It is also possible to run FDPIC ELF binaries on MMU linux also. |
42 | 42 | ||
43 | config BINFMT_FLAT | 43 | config BINFMT_FLAT |
44 | tristate "Kernel support for flat binaries" | 44 | bool "Kernel support for flat binaries" |
45 | depends on !MMU | 45 | depends on !MMU |
46 | help | 46 | help |
47 | Support uClinux FLAT format binaries. | 47 | Support uClinux FLAT format binaries. |
diff --git a/fs/adfs/dir_f.c b/fs/adfs/dir_f.c index b9b2b27b68c3..ea7df2146921 100644 --- a/fs/adfs/dir_f.c +++ b/fs/adfs/dir_f.c | |||
@@ -122,9 +122,9 @@ adfs_dir_checkbyte(const struct adfs_dir *dir) | |||
122 | ptr.ptr8 = bufoff(bh, i); | 122 | ptr.ptr8 = bufoff(bh, i); |
123 | end.ptr8 = ptr.ptr8 + last - i; | 123 | end.ptr8 = ptr.ptr8 + last - i; |
124 | 124 | ||
125 | do | 125 | do { |
126 | dircheck = *ptr.ptr8++ ^ ror13(dircheck); | 126 | dircheck = *ptr.ptr8++ ^ ror13(dircheck); |
127 | while (ptr.ptr8 < end.ptr8); | 127 | } while (ptr.ptr8 < end.ptr8); |
128 | } | 128 | } |
129 | 129 | ||
130 | /* | 130 | /* |
diff --git a/fs/affs/file.c b/fs/affs/file.c index 6e0c9399200e..e87ede608f77 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c | |||
@@ -325,8 +325,7 @@ affs_get_block(struct inode *inode, sector_t block, struct buffer_head *bh_resul | |||
325 | pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block); | 325 | pr_debug("AFFS: get_block(%u, %lu)\n", (u32)inode->i_ino, (unsigned long)block); |
326 | 326 | ||
327 | 327 | ||
328 | if (block > (sector_t)0x7fffffffUL) | 328 | BUG_ON(block > (sector_t)0x7fffffffUL); |
329 | BUG(); | ||
330 | 329 | ||
331 | if (block >= AFFS_I(inode)->i_blkcnt) { | 330 | if (block >= AFFS_I(inode)->i_blkcnt) { |
332 | if (block > AFFS_I(inode)->i_blkcnt || !create) | 331 | if (block > AFFS_I(inode)->i_blkcnt || !create) |
@@ -493,8 +492,7 @@ affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsign | |||
493 | u32 tmp; | 492 | u32 tmp; |
494 | 493 | ||
495 | pr_debug("AFFS: read_page(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to); | 494 | pr_debug("AFFS: read_page(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to); |
496 | if (from > to || to > PAGE_CACHE_SIZE) | 495 | BUG_ON(from > to || to > PAGE_CACHE_SIZE); |
497 | BUG(); | ||
498 | kmap(page); | 496 | kmap(page); |
499 | data = page_address(page); | 497 | data = page_address(page); |
500 | bsize = AFFS_SB(sb)->s_data_blksize; | 498 | bsize = AFFS_SB(sb)->s_data_blksize; |
@@ -507,8 +505,7 @@ affs_do_readpage_ofs(struct file *file, struct page *page, unsigned from, unsign | |||
507 | if (IS_ERR(bh)) | 505 | if (IS_ERR(bh)) |
508 | return PTR_ERR(bh); | 506 | return PTR_ERR(bh); |
509 | tmp = min(bsize - boff, to - from); | 507 | tmp = min(bsize - boff, to - from); |
510 | if (from + tmp > to || tmp > bsize) | 508 | BUG_ON(from + tmp > to || tmp > bsize); |
511 | BUG(); | ||
512 | memcpy(data + from, AFFS_DATA(bh) + boff, tmp); | 509 | memcpy(data + from, AFFS_DATA(bh) + boff, tmp); |
513 | affs_brelse(bh); | 510 | affs_brelse(bh); |
514 | bidx++; | 511 | bidx++; |
@@ -540,8 +537,7 @@ affs_extent_file_ofs(struct inode *inode, u32 newsize) | |||
540 | if (IS_ERR(bh)) | 537 | if (IS_ERR(bh)) |
541 | return PTR_ERR(bh); | 538 | return PTR_ERR(bh); |
542 | tmp = min(bsize - boff, newsize - size); | 539 | tmp = min(bsize - boff, newsize - size); |
543 | if (boff + tmp > bsize || tmp > bsize) | 540 | BUG_ON(boff + tmp > bsize || tmp > bsize); |
544 | BUG(); | ||
545 | memset(AFFS_DATA(bh) + boff, 0, tmp); | 541 | memset(AFFS_DATA(bh) + boff, 0, tmp); |
546 | AFFS_DATA_HEAD(bh)->size = cpu_to_be32(be32_to_cpu(AFFS_DATA_HEAD(bh)->size) + tmp); | 542 | AFFS_DATA_HEAD(bh)->size = cpu_to_be32(be32_to_cpu(AFFS_DATA_HEAD(bh)->size) + tmp); |
547 | affs_fix_checksum(sb, bh); | 543 | affs_fix_checksum(sb, bh); |
@@ -560,8 +556,7 @@ affs_extent_file_ofs(struct inode *inode, u32 newsize) | |||
560 | if (IS_ERR(bh)) | 556 | if (IS_ERR(bh)) |
561 | goto out; | 557 | goto out; |
562 | tmp = min(bsize, newsize - size); | 558 | tmp = min(bsize, newsize - size); |
563 | if (tmp > bsize) | 559 | BUG_ON(tmp > bsize); |
564 | BUG(); | ||
565 | AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA); | 560 | AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA); |
566 | AFFS_DATA_HEAD(bh)->key = cpu_to_be32(inode->i_ino); | 561 | AFFS_DATA_HEAD(bh)->key = cpu_to_be32(inode->i_ino); |
567 | AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx); | 562 | AFFS_DATA_HEAD(bh)->sequence = cpu_to_be32(bidx); |
@@ -683,8 +678,7 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping, | |||
683 | if (IS_ERR(bh)) | 678 | if (IS_ERR(bh)) |
684 | return PTR_ERR(bh); | 679 | return PTR_ERR(bh); |
685 | tmp = min(bsize - boff, to - from); | 680 | tmp = min(bsize - boff, to - from); |
686 | if (boff + tmp > bsize || tmp > bsize) | 681 | BUG_ON(boff + tmp > bsize || tmp > bsize); |
687 | BUG(); | ||
688 | memcpy(AFFS_DATA(bh) + boff, data + from, tmp); | 682 | memcpy(AFFS_DATA(bh) + boff, data + from, tmp); |
689 | AFFS_DATA_HEAD(bh)->size = cpu_to_be32(be32_to_cpu(AFFS_DATA_HEAD(bh)->size) + tmp); | 683 | AFFS_DATA_HEAD(bh)->size = cpu_to_be32(be32_to_cpu(AFFS_DATA_HEAD(bh)->size) + tmp); |
690 | affs_fix_checksum(sb, bh); | 684 | affs_fix_checksum(sb, bh); |
@@ -732,8 +726,7 @@ static int affs_write_end_ofs(struct file *file, struct address_space *mapping, | |||
732 | if (IS_ERR(bh)) | 726 | if (IS_ERR(bh)) |
733 | goto out; | 727 | goto out; |
734 | tmp = min(bsize, to - from); | 728 | tmp = min(bsize, to - from); |
735 | if (tmp > bsize) | 729 | BUG_ON(tmp > bsize); |
736 | BUG(); | ||
737 | memcpy(AFFS_DATA(bh), data + from, tmp); | 730 | memcpy(AFFS_DATA(bh), data + from, tmp); |
738 | if (buffer_new(bh)) { | 731 | if (buffer_new(bh)) { |
739 | AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA); | 732 | AFFS_DATA_HEAD(bh)->ptype = cpu_to_be32(T_DATA); |
diff --git a/fs/affs/super.c b/fs/affs/super.c index d2dc047cb479..01d25d532541 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -199,7 +199,6 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s | |||
199 | case Opt_prefix: | 199 | case Opt_prefix: |
200 | /* Free any previous prefix */ | 200 | /* Free any previous prefix */ |
201 | kfree(*prefix); | 201 | kfree(*prefix); |
202 | *prefix = NULL; | ||
203 | *prefix = match_strdup(&args[0]); | 202 | *prefix = match_strdup(&args[0]); |
204 | if (!*prefix) | 203 | if (!*prefix) |
205 | return 0; | 204 | return 0; |
@@ -233,6 +232,8 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s | |||
233 | break; | 232 | break; |
234 | case Opt_volume: { | 233 | case Opt_volume: { |
235 | char *vol = match_strdup(&args[0]); | 234 | char *vol = match_strdup(&args[0]); |
235 | if (!vol) | ||
236 | return 0; | ||
236 | strlcpy(volume, vol, 32); | 237 | strlcpy(volume, vol, 32); |
237 | kfree(vol); | 238 | kfree(vol); |
238 | break; | 239 | break; |
diff --git a/fs/afs/afs_cm.h b/fs/afs/afs_cm.h index 7b4d4fab4c80..255f5dd6040c 100644 --- a/fs/afs/afs_cm.h +++ b/fs/afs/afs_cm.h | |||
@@ -24,7 +24,8 @@ enum AFS_CM_Operations { | |||
24 | CBGetXStatsVersion = 209, /* get version of extended statistics */ | 24 | CBGetXStatsVersion = 209, /* get version of extended statistics */ |
25 | CBGetXStats = 210, /* get contents of extended statistics data */ | 25 | CBGetXStats = 210, /* get contents of extended statistics data */ |
26 | CBInitCallBackState3 = 213, /* initialise callback state, version 3 */ | 26 | CBInitCallBackState3 = 213, /* initialise callback state, version 3 */ |
27 | CBGetCapabilities = 65538, /* get client capabilities */ | 27 | CBProbeUuid = 214, /* check the client hasn't rebooted */ |
28 | CBTellMeAboutYourself = 65538, /* get client capabilities */ | ||
28 | }; | 29 | }; |
29 | 30 | ||
30 | #define AFS_CAP_ERROR_TRANSLATION 0x1 | 31 | #define AFS_CAP_ERROR_TRANSLATION 0x1 |
diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 584bb0f9c36a..5e1df14e16b1 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c | |||
@@ -20,7 +20,7 @@ | |||
20 | DECLARE_RWSEM(afs_proc_cells_sem); | 20 | DECLARE_RWSEM(afs_proc_cells_sem); |
21 | LIST_HEAD(afs_proc_cells); | 21 | LIST_HEAD(afs_proc_cells); |
22 | 22 | ||
23 | static struct list_head afs_cells = LIST_HEAD_INIT(afs_cells); | 23 | static LIST_HEAD(afs_cells); |
24 | static DEFINE_RWLOCK(afs_cells_lock); | 24 | static DEFINE_RWLOCK(afs_cells_lock); |
25 | static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */ | 25 | static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */ |
26 | static DECLARE_WAIT_QUEUE_HEAD(afs_cells_freeable_wq); | 26 | static DECLARE_WAIT_QUEUE_HEAD(afs_cells_freeable_wq); |
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 47b71c8947f9..eb765489164f 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c | |||
@@ -26,8 +26,9 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *, | |||
26 | struct sk_buff *, bool); | 26 | struct sk_buff *, bool); |
27 | static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool); | 27 | static int afs_deliver_cb_probe(struct afs_call *, struct sk_buff *, bool); |
28 | static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool); | 28 | static int afs_deliver_cb_callback(struct afs_call *, struct sk_buff *, bool); |
29 | static int afs_deliver_cb_get_capabilities(struct afs_call *, struct sk_buff *, | 29 | static int afs_deliver_cb_probe_uuid(struct afs_call *, struct sk_buff *, bool); |
30 | bool); | 30 | static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *, |
31 | struct sk_buff *, bool); | ||
31 | static void afs_cm_destructor(struct afs_call *); | 32 | static void afs_cm_destructor(struct afs_call *); |
32 | 33 | ||
33 | /* | 34 | /* |
@@ -71,11 +72,21 @@ static const struct afs_call_type afs_SRXCBProbe = { | |||
71 | }; | 72 | }; |
72 | 73 | ||
73 | /* | 74 | /* |
74 | * CB.GetCapabilities operation type | 75 | * CB.ProbeUuid operation type |
75 | */ | 76 | */ |
76 | static const struct afs_call_type afs_SRXCBGetCapabilites = { | 77 | static const struct afs_call_type afs_SRXCBProbeUuid = { |
77 | .name = "CB.GetCapabilities", | 78 | .name = "CB.ProbeUuid", |
78 | .deliver = afs_deliver_cb_get_capabilities, | 79 | .deliver = afs_deliver_cb_probe_uuid, |
80 | .abort_to_error = afs_abort_to_error, | ||
81 | .destructor = afs_cm_destructor, | ||
82 | }; | ||
83 | |||
84 | /* | ||
85 | * CB.TellMeAboutYourself operation type | ||
86 | */ | ||
87 | static const struct afs_call_type afs_SRXCBTellMeAboutYourself = { | ||
88 | .name = "CB.TellMeAboutYourself", | ||
89 | .deliver = afs_deliver_cb_tell_me_about_yourself, | ||
79 | .abort_to_error = afs_abort_to_error, | 90 | .abort_to_error = afs_abort_to_error, |
80 | .destructor = afs_cm_destructor, | 91 | .destructor = afs_cm_destructor, |
81 | }; | 92 | }; |
@@ -103,8 +114,8 @@ bool afs_cm_incoming_call(struct afs_call *call) | |||
103 | case CBProbe: | 114 | case CBProbe: |
104 | call->type = &afs_SRXCBProbe; | 115 | call->type = &afs_SRXCBProbe; |
105 | return true; | 116 | return true; |
106 | case CBGetCapabilities: | 117 | case CBTellMeAboutYourself: |
107 | call->type = &afs_SRXCBGetCapabilites; | 118 | call->type = &afs_SRXCBTellMeAboutYourself; |
108 | return true; | 119 | return true; |
109 | default: | 120 | default: |
110 | return false; | 121 | return false; |
@@ -393,9 +404,105 @@ static int afs_deliver_cb_probe(struct afs_call *call, struct sk_buff *skb, | |||
393 | } | 404 | } |
394 | 405 | ||
395 | /* | 406 | /* |
407 | * allow the fileserver to quickly find out if the fileserver has been rebooted | ||
408 | */ | ||
409 | static void SRXAFSCB_ProbeUuid(struct work_struct *work) | ||
410 | { | ||
411 | struct afs_call *call = container_of(work, struct afs_call, work); | ||
412 | struct afs_uuid *r = call->request; | ||
413 | |||
414 | struct { | ||
415 | __be32 match; | ||
416 | } reply; | ||
417 | |||
418 | _enter(""); | ||
419 | |||
420 | |||
421 | if (memcmp(r, &afs_uuid, sizeof(afs_uuid)) == 0) | ||
422 | reply.match = htonl(0); | ||
423 | else | ||
424 | reply.match = htonl(1); | ||
425 | |||
426 | afs_send_simple_reply(call, &reply, sizeof(reply)); | ||
427 | _leave(""); | ||
428 | } | ||
429 | |||
430 | /* | ||
431 | * deliver request data to a CB.ProbeUuid call | ||
432 | */ | ||
433 | static int afs_deliver_cb_probe_uuid(struct afs_call *call, struct sk_buff *skb, | ||
434 | bool last) | ||
435 | { | ||
436 | struct afs_uuid *r; | ||
437 | unsigned loop; | ||
438 | __be32 *b; | ||
439 | int ret; | ||
440 | |||
441 | _enter("{%u},{%u},%d", call->unmarshall, skb->len, last); | ||
442 | |||
443 | if (skb->len > 0) | ||
444 | return -EBADMSG; | ||
445 | if (!last) | ||
446 | return 0; | ||
447 | |||
448 | switch (call->unmarshall) { | ||
449 | case 0: | ||
450 | call->offset = 0; | ||
451 | call->buffer = kmalloc(11 * sizeof(__be32), GFP_KERNEL); | ||
452 | if (!call->buffer) | ||
453 | return -ENOMEM; | ||
454 | call->unmarshall++; | ||
455 | |||
456 | case 1: | ||
457 | _debug("extract UUID"); | ||
458 | ret = afs_extract_data(call, skb, last, call->buffer, | ||
459 | 11 * sizeof(__be32)); | ||
460 | switch (ret) { | ||
461 | case 0: break; | ||
462 | case -EAGAIN: return 0; | ||
463 | default: return ret; | ||
464 | } | ||
465 | |||
466 | _debug("unmarshall UUID"); | ||
467 | call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL); | ||
468 | if (!call->request) | ||
469 | return -ENOMEM; | ||
470 | |||
471 | b = call->buffer; | ||
472 | r = call->request; | ||
473 | r->time_low = ntohl(b[0]); | ||
474 | r->time_mid = ntohl(b[1]); | ||
475 | r->time_hi_and_version = ntohl(b[2]); | ||
476 | r->clock_seq_hi_and_reserved = ntohl(b[3]); | ||
477 | r->clock_seq_low = ntohl(b[4]); | ||
478 | |||
479 | for (loop = 0; loop < 6; loop++) | ||
480 | r->node[loop] = ntohl(b[loop + 5]); | ||
481 | |||
482 | call->offset = 0; | ||
483 | call->unmarshall++; | ||
484 | |||
485 | case 2: | ||
486 | _debug("trailer"); | ||
487 | if (skb->len != 0) | ||
488 | return -EBADMSG; | ||
489 | break; | ||
490 | } | ||
491 | |||
492 | if (!last) | ||
493 | return 0; | ||
494 | |||
495 | call->state = AFS_CALL_REPLYING; | ||
496 | |||
497 | INIT_WORK(&call->work, SRXAFSCB_ProbeUuid); | ||
498 | schedule_work(&call->work); | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | /* | ||
396 | * allow the fileserver to ask about the cache manager's capabilities | 503 | * allow the fileserver to ask about the cache manager's capabilities |
397 | */ | 504 | */ |
398 | static void SRXAFSCB_GetCapabilities(struct work_struct *work) | 505 | static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work) |
399 | { | 506 | { |
400 | struct afs_interface *ifs; | 507 | struct afs_interface *ifs; |
401 | struct afs_call *call = container_of(work, struct afs_call, work); | 508 | struct afs_call *call = container_of(work, struct afs_call, work); |
@@ -456,10 +563,10 @@ static void SRXAFSCB_GetCapabilities(struct work_struct *work) | |||
456 | } | 563 | } |
457 | 564 | ||
458 | /* | 565 | /* |
459 | * deliver request data to a CB.GetCapabilities call | 566 | * deliver request data to a CB.TellMeAboutYourself call |
460 | */ | 567 | */ |
461 | static int afs_deliver_cb_get_capabilities(struct afs_call *call, | 568 | static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call, |
462 | struct sk_buff *skb, bool last) | 569 | struct sk_buff *skb, bool last) |
463 | { | 570 | { |
464 | _enter(",{%u},%d", skb->len, last); | 571 | _enter(",{%u},%d", skb->len, last); |
465 | 572 | ||
@@ -471,7 +578,7 @@ static int afs_deliver_cb_get_capabilities(struct afs_call *call, | |||
471 | /* no unmarshalling required */ | 578 | /* no unmarshalling required */ |
472 | call->state = AFS_CALL_REPLYING; | 579 | call->state = AFS_CALL_REPLYING; |
473 | 580 | ||
474 | INIT_WORK(&call->work, SRXAFSCB_GetCapabilities); | 581 | INIT_WORK(&call->work, SRXAFSCB_TellMeAboutYourself); |
475 | schedule_work(&call->work); | 582 | schedule_work(&call->work); |
476 | return 0; | 583 | return 0; |
477 | } | 584 | } |
diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 846c7615ac9e..9f7d1ae70269 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c | |||
@@ -41,6 +41,7 @@ static const struct file_operations afs_proc_cells_fops = { | |||
41 | .write = afs_proc_cells_write, | 41 | .write = afs_proc_cells_write, |
42 | .llseek = seq_lseek, | 42 | .llseek = seq_lseek, |
43 | .release = seq_release, | 43 | .release = seq_release, |
44 | .owner = THIS_MODULE, | ||
44 | }; | 45 | }; |
45 | 46 | ||
46 | static int afs_proc_rootcell_open(struct inode *inode, struct file *file); | 47 | static int afs_proc_rootcell_open(struct inode *inode, struct file *file); |
@@ -56,7 +57,8 @@ static const struct file_operations afs_proc_rootcell_fops = { | |||
56 | .read = afs_proc_rootcell_read, | 57 | .read = afs_proc_rootcell_read, |
57 | .write = afs_proc_rootcell_write, | 58 | .write = afs_proc_rootcell_write, |
58 | .llseek = no_llseek, | 59 | .llseek = no_llseek, |
59 | .release = afs_proc_rootcell_release | 60 | .release = afs_proc_rootcell_release, |
61 | .owner = THIS_MODULE, | ||
60 | }; | 62 | }; |
61 | 63 | ||
62 | static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file); | 64 | static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file); |
@@ -80,6 +82,7 @@ static const struct file_operations afs_proc_cell_volumes_fops = { | |||
80 | .read = seq_read, | 82 | .read = seq_read, |
81 | .llseek = seq_lseek, | 83 | .llseek = seq_lseek, |
82 | .release = afs_proc_cell_volumes_release, | 84 | .release = afs_proc_cell_volumes_release, |
85 | .owner = THIS_MODULE, | ||
83 | }; | 86 | }; |
84 | 87 | ||
85 | static int afs_proc_cell_vlservers_open(struct inode *inode, | 88 | static int afs_proc_cell_vlservers_open(struct inode *inode, |
@@ -104,6 +107,7 @@ static const struct file_operations afs_proc_cell_vlservers_fops = { | |||
104 | .read = seq_read, | 107 | .read = seq_read, |
105 | .llseek = seq_lseek, | 108 | .llseek = seq_lseek, |
106 | .release = afs_proc_cell_vlservers_release, | 109 | .release = afs_proc_cell_vlservers_release, |
110 | .owner = THIS_MODULE, | ||
107 | }; | 111 | }; |
108 | 112 | ||
109 | static int afs_proc_cell_servers_open(struct inode *inode, struct file *file); | 113 | static int afs_proc_cell_servers_open(struct inode *inode, struct file *file); |
@@ -127,6 +131,7 @@ static const struct file_operations afs_proc_cell_servers_fops = { | |||
127 | .read = seq_read, | 131 | .read = seq_read, |
128 | .llseek = seq_lseek, | 132 | .llseek = seq_lseek, |
129 | .release = afs_proc_cell_servers_release, | 133 | .release = afs_proc_cell_servers_release, |
134 | .owner = THIS_MODULE, | ||
130 | }; | 135 | }; |
131 | 136 | ||
132 | /* | 137 | /* |
@@ -143,17 +148,13 @@ int afs_proc_init(void) | |||
143 | goto error_dir; | 148 | goto error_dir; |
144 | proc_afs->owner = THIS_MODULE; | 149 | proc_afs->owner = THIS_MODULE; |
145 | 150 | ||
146 | p = create_proc_entry("cells", 0, proc_afs); | 151 | p = proc_create("cells", 0, proc_afs, &afs_proc_cells_fops); |
147 | if (!p) | 152 | if (!p) |
148 | goto error_cells; | 153 | goto error_cells; |
149 | p->proc_fops = &afs_proc_cells_fops; | ||
150 | p->owner = THIS_MODULE; | ||
151 | 154 | ||
152 | p = create_proc_entry("rootcell", 0, proc_afs); | 155 | p = proc_create("rootcell", 0, proc_afs, &afs_proc_rootcell_fops); |
153 | if (!p) | 156 | if (!p) |
154 | goto error_rootcell; | 157 | goto error_rootcell; |
155 | p->proc_fops = &afs_proc_rootcell_fops; | ||
156 | p->owner = THIS_MODULE; | ||
157 | 158 | ||
158 | _leave(" = 0"); | 159 | _leave(" = 0"); |
159 | return 0; | 160 | return 0; |
@@ -395,26 +396,20 @@ int afs_proc_cell_setup(struct afs_cell *cell) | |||
395 | if (!cell->proc_dir) | 396 | if (!cell->proc_dir) |
396 | goto error_dir; | 397 | goto error_dir; |
397 | 398 | ||
398 | p = create_proc_entry("servers", 0, cell->proc_dir); | 399 | p = proc_create_data("servers", 0, cell->proc_dir, |
400 | &afs_proc_cell_servers_fops, cell); | ||
399 | if (!p) | 401 | if (!p) |
400 | goto error_servers; | 402 | goto error_servers; |
401 | p->proc_fops = &afs_proc_cell_servers_fops; | ||
402 | p->owner = THIS_MODULE; | ||
403 | p->data = cell; | ||
404 | 403 | ||
405 | p = create_proc_entry("vlservers", 0, cell->proc_dir); | 404 | p = proc_create_data("vlservers", 0, cell->proc_dir, |
405 | &afs_proc_cell_vlservers_fops, cell); | ||
406 | if (!p) | 406 | if (!p) |
407 | goto error_vlservers; | 407 | goto error_vlservers; |
408 | p->proc_fops = &afs_proc_cell_vlservers_fops; | ||
409 | p->owner = THIS_MODULE; | ||
410 | p->data = cell; | ||
411 | 408 | ||
412 | p = create_proc_entry("volumes", 0, cell->proc_dir); | 409 | p = proc_create_data("volumes", 0, cell->proc_dir, |
410 | &afs_proc_cell_volumes_fops, cell); | ||
413 | if (!p) | 411 | if (!p) |
414 | goto error_volumes; | 412 | goto error_volumes; |
415 | p->proc_fops = &afs_proc_cell_volumes_fops; | ||
416 | p->owner = THIS_MODULE; | ||
417 | p->data = cell; | ||
418 | 413 | ||
419 | _leave(" = 0"); | 414 | _leave(" = 0"); |
420 | return 0; | 415 | return 0; |
@@ -191,6 +191,43 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
191 | kunmap_atomic((void *)((unsigned long)__event & PAGE_MASK), km); \ | 191 | kunmap_atomic((void *)((unsigned long)__event & PAGE_MASK), km); \ |
192 | } while(0) | 192 | } while(0) |
193 | 193 | ||
194 | |||
195 | /* __put_ioctx | ||
196 | * Called when the last user of an aio context has gone away, | ||
197 | * and the struct needs to be freed. | ||
198 | */ | ||
199 | static void __put_ioctx(struct kioctx *ctx) | ||
200 | { | ||
201 | unsigned nr_events = ctx->max_reqs; | ||
202 | |||
203 | BUG_ON(ctx->reqs_active); | ||
204 | |||
205 | cancel_delayed_work(&ctx->wq); | ||
206 | cancel_work_sync(&ctx->wq.work); | ||
207 | aio_free_ring(ctx); | ||
208 | mmdrop(ctx->mm); | ||
209 | ctx->mm = NULL; | ||
210 | pr_debug("__put_ioctx: freeing %p\n", ctx); | ||
211 | kmem_cache_free(kioctx_cachep, ctx); | ||
212 | |||
213 | if (nr_events) { | ||
214 | spin_lock(&aio_nr_lock); | ||
215 | BUG_ON(aio_nr - nr_events > aio_nr); | ||
216 | aio_nr -= nr_events; | ||
217 | spin_unlock(&aio_nr_lock); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | #define get_ioctx(kioctx) do { \ | ||
222 | BUG_ON(atomic_read(&(kioctx)->users) <= 0); \ | ||
223 | atomic_inc(&(kioctx)->users); \ | ||
224 | } while (0) | ||
225 | #define put_ioctx(kioctx) do { \ | ||
226 | BUG_ON(atomic_read(&(kioctx)->users) <= 0); \ | ||
227 | if (unlikely(atomic_dec_and_test(&(kioctx)->users))) \ | ||
228 | __put_ioctx(kioctx); \ | ||
229 | } while (0) | ||
230 | |||
194 | /* ioctx_alloc | 231 | /* ioctx_alloc |
195 | * Allocates and initializes an ioctx. Returns an ERR_PTR if it failed. | 232 | * Allocates and initializes an ioctx. Returns an ERR_PTR if it failed. |
196 | */ | 233 | */ |
@@ -240,7 +277,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) | |||
240 | if (ctx->max_reqs == 0) | 277 | if (ctx->max_reqs == 0) |
241 | goto out_cleanup; | 278 | goto out_cleanup; |
242 | 279 | ||
243 | /* now link into global list. kludge. FIXME */ | 280 | /* now link into global list. */ |
244 | write_lock(&mm->ioctx_list_lock); | 281 | write_lock(&mm->ioctx_list_lock); |
245 | ctx->next = mm->ioctx_list; | 282 | ctx->next = mm->ioctx_list; |
246 | mm->ioctx_list = ctx; | 283 | mm->ioctx_list = ctx; |
@@ -361,32 +398,6 @@ void exit_aio(struct mm_struct *mm) | |||
361 | } | 398 | } |
362 | } | 399 | } |
363 | 400 | ||
364 | /* __put_ioctx | ||
365 | * Called when the last user of an aio context has gone away, | ||
366 | * and the struct needs to be freed. | ||
367 | */ | ||
368 | void __put_ioctx(struct kioctx *ctx) | ||
369 | { | ||
370 | unsigned nr_events = ctx->max_reqs; | ||
371 | |||
372 | BUG_ON(ctx->reqs_active); | ||
373 | |||
374 | cancel_delayed_work(&ctx->wq); | ||
375 | cancel_work_sync(&ctx->wq.work); | ||
376 | aio_free_ring(ctx); | ||
377 | mmdrop(ctx->mm); | ||
378 | ctx->mm = NULL; | ||
379 | pr_debug("__put_ioctx: freeing %p\n", ctx); | ||
380 | kmem_cache_free(kioctx_cachep, ctx); | ||
381 | |||
382 | if (nr_events) { | ||
383 | spin_lock(&aio_nr_lock); | ||
384 | BUG_ON(aio_nr - nr_events > aio_nr); | ||
385 | aio_nr -= nr_events; | ||
386 | spin_unlock(&aio_nr_lock); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | /* aio_get_req | 401 | /* aio_get_req |
391 | * Allocate a slot for an aio request. Increments the users count | 402 | * Allocate a slot for an aio request. Increments the users count |
392 | * of the kioctx so that the kioctx stays around until all requests are | 403 | * of the kioctx so that the kioctx stays around until all requests are |
@@ -542,10 +553,7 @@ int aio_put_req(struct kiocb *req) | |||
542 | return ret; | 553 | return ret; |
543 | } | 554 | } |
544 | 555 | ||
545 | /* Lookup an ioctx id. ioctx_list is lockless for reads. | 556 | static struct kioctx *lookup_ioctx(unsigned long ctx_id) |
546 | * FIXME: this is O(n) and is only suitable for development. | ||
547 | */ | ||
548 | struct kioctx *lookup_ioctx(unsigned long ctx_id) | ||
549 | { | 557 | { |
550 | struct kioctx *ioctx; | 558 | struct kioctx *ioctx; |
551 | struct mm_struct *mm; | 559 | struct mm_struct *mm; |
@@ -1552,7 +1560,7 @@ static int aio_wake_function(wait_queue_t *wait, unsigned mode, | |||
1552 | return 1; | 1560 | return 1; |
1553 | } | 1561 | } |
1554 | 1562 | ||
1555 | int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | 1563 | static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, |
1556 | struct iocb *iocb) | 1564 | struct iocb *iocb) |
1557 | { | 1565 | { |
1558 | struct kiocb *req; | 1566 | struct kiocb *req; |
@@ -1593,7 +1601,7 @@ int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, | |||
1593 | * event using the eventfd_signal() function. | 1601 | * event using the eventfd_signal() function. |
1594 | */ | 1602 | */ |
1595 | req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd); | 1603 | req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd); |
1596 | if (unlikely(IS_ERR(req->ki_eventfd))) { | 1604 | if (IS_ERR(req->ki_eventfd)) { |
1597 | ret = PTR_ERR(req->ki_eventfd); | 1605 | ret = PTR_ERR(req->ki_eventfd); |
1598 | goto out_put_req; | 1606 | goto out_put_req; |
1599 | } | 1607 | } |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index a54a946a50ae..aa4c5ff8a40d 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -533,9 +533,9 @@ static struct dentry *autofs4_lookup_unhashed(struct autofs_sb_info *sbi, struct | |||
533 | goto next; | 533 | goto next; |
534 | 534 | ||
535 | if (d_unhashed(dentry)) { | 535 | if (d_unhashed(dentry)) { |
536 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | ||
537 | struct inode *inode = dentry->d_inode; | 536 | struct inode *inode = dentry->d_inode; |
538 | 537 | ||
538 | ino = autofs4_dentry_ino(dentry); | ||
539 | list_del_init(&ino->rehash); | 539 | list_del_init(&ino->rehash); |
540 | dget(dentry); | 540 | dget(dentry); |
541 | /* | 541 | /* |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index 82123ff3e1dd..e8717de3bab3 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -489,9 +489,9 @@ static void befs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) | |||
489 | { | 489 | { |
490 | befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); | 490 | befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); |
491 | if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { | 491 | if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { |
492 | char *p = nd_get_link(nd); | 492 | char *link = nd_get_link(nd); |
493 | if (!IS_ERR(p)) | 493 | if (!IS_ERR(link)) |
494 | kfree(p); | 494 | kfree(link); |
495 | } | 495 | } |
496 | } | 496 | } |
497 | 497 | ||
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index a1bb2244cac7..ba4cddb92f1d 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -372,21 +372,17 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
372 | 372 | ||
373 | flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data); | 373 | flush_icache_range(text_addr, text_addr+ex.a_text+ex.a_data); |
374 | } else { | 374 | } else { |
375 | static unsigned long error_time, error_time2; | ||
376 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && | 375 | if ((ex.a_text & 0xfff || ex.a_data & 0xfff) && |
377 | (N_MAGIC(ex) != NMAGIC) && (jiffies-error_time2) > 5*HZ) | 376 | (N_MAGIC(ex) != NMAGIC) && printk_ratelimit()) |
378 | { | 377 | { |
379 | printk(KERN_NOTICE "executable not page aligned\n"); | 378 | printk(KERN_NOTICE "executable not page aligned\n"); |
380 | error_time2 = jiffies; | ||
381 | } | 379 | } |
382 | 380 | ||
383 | if ((fd_offset & ~PAGE_MASK) != 0 && | 381 | if ((fd_offset & ~PAGE_MASK) != 0 && printk_ratelimit()) |
384 | (jiffies-error_time) > 5*HZ) | ||
385 | { | 382 | { |
386 | printk(KERN_WARNING | 383 | printk(KERN_WARNING |
387 | "fd_offset is not page aligned. Please convert program: %s\n", | 384 | "fd_offset is not page aligned. Please convert program: %s\n", |
388 | bprm->file->f_path.dentry->d_name.name); | 385 | bprm->file->f_path.dentry->d_name.name); |
389 | error_time = jiffies; | ||
390 | } | 386 | } |
391 | 387 | ||
392 | if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { | 388 | if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { |
@@ -495,15 +491,13 @@ static int load_aout_library(struct file *file) | |||
495 | start_addr = ex.a_entry & 0xfffff000; | 491 | start_addr = ex.a_entry & 0xfffff000; |
496 | 492 | ||
497 | if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) { | 493 | if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) { |
498 | static unsigned long error_time; | ||
499 | loff_t pos = N_TXTOFF(ex); | 494 | loff_t pos = N_TXTOFF(ex); |
500 | 495 | ||
501 | if ((jiffies-error_time) > 5*HZ) | 496 | if (printk_ratelimit()) |
502 | { | 497 | { |
503 | printk(KERN_WARNING | 498 | printk(KERN_WARNING |
504 | "N_TXTOFF is not page aligned. Please convert library: %s\n", | 499 | "N_TXTOFF is not page aligned. Please convert library: %s\n", |
505 | file->f_path.dentry->d_name.name); | 500 | file->f_path.dentry->d_name.name); |
506 | error_time = jiffies; | ||
507 | } | 501 | } |
508 | down_write(¤t->mm->mmap_sem); | 502 | down_write(¤t->mm->mmap_sem); |
509 | do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); | 503 | do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 9924581df6f6..b25707fee2cc 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1255,26 +1255,23 @@ static int writenote(struct memelfnote *men, struct file *file, | |||
1255 | static void fill_elf_header(struct elfhdr *elf, int segs, | 1255 | static void fill_elf_header(struct elfhdr *elf, int segs, |
1256 | u16 machine, u32 flags, u8 osabi) | 1256 | u16 machine, u32 flags, u8 osabi) |
1257 | { | 1257 | { |
1258 | memset(elf, 0, sizeof(*elf)); | ||
1259 | |||
1258 | memcpy(elf->e_ident, ELFMAG, SELFMAG); | 1260 | memcpy(elf->e_ident, ELFMAG, SELFMAG); |
1259 | elf->e_ident[EI_CLASS] = ELF_CLASS; | 1261 | elf->e_ident[EI_CLASS] = ELF_CLASS; |
1260 | elf->e_ident[EI_DATA] = ELF_DATA; | 1262 | elf->e_ident[EI_DATA] = ELF_DATA; |
1261 | elf->e_ident[EI_VERSION] = EV_CURRENT; | 1263 | elf->e_ident[EI_VERSION] = EV_CURRENT; |
1262 | elf->e_ident[EI_OSABI] = ELF_OSABI; | 1264 | elf->e_ident[EI_OSABI] = ELF_OSABI; |
1263 | memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); | ||
1264 | 1265 | ||
1265 | elf->e_type = ET_CORE; | 1266 | elf->e_type = ET_CORE; |
1266 | elf->e_machine = machine; | 1267 | elf->e_machine = machine; |
1267 | elf->e_version = EV_CURRENT; | 1268 | elf->e_version = EV_CURRENT; |
1268 | elf->e_entry = 0; | ||
1269 | elf->e_phoff = sizeof(struct elfhdr); | 1269 | elf->e_phoff = sizeof(struct elfhdr); |
1270 | elf->e_shoff = 0; | ||
1271 | elf->e_flags = flags; | 1270 | elf->e_flags = flags; |
1272 | elf->e_ehsize = sizeof(struct elfhdr); | 1271 | elf->e_ehsize = sizeof(struct elfhdr); |
1273 | elf->e_phentsize = sizeof(struct elf_phdr); | 1272 | elf->e_phentsize = sizeof(struct elf_phdr); |
1274 | elf->e_phnum = segs; | 1273 | elf->e_phnum = segs; |
1275 | elf->e_shentsize = 0; | 1274 | |
1276 | elf->e_shnum = 0; | ||
1277 | elf->e_shstrndx = 0; | ||
1278 | return; | 1275 | return; |
1279 | } | 1276 | } |
1280 | 1277 | ||
@@ -1725,26 +1722,25 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, | |||
1725 | 1722 | ||
1726 | info->thread_status_size = 0; | 1723 | info->thread_status_size = 0; |
1727 | if (signr) { | 1724 | if (signr) { |
1728 | struct elf_thread_status *tmp; | 1725 | struct elf_thread_status *ets; |
1729 | rcu_read_lock(); | 1726 | rcu_read_lock(); |
1730 | do_each_thread(g, p) | 1727 | do_each_thread(g, p) |
1731 | if (current->mm == p->mm && current != p) { | 1728 | if (current->mm == p->mm && current != p) { |
1732 | tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); | 1729 | ets = kzalloc(sizeof(*ets), GFP_ATOMIC); |
1733 | if (!tmp) { | 1730 | if (!ets) { |
1734 | rcu_read_unlock(); | 1731 | rcu_read_unlock(); |
1735 | return 0; | 1732 | return 0; |
1736 | } | 1733 | } |
1737 | tmp->thread = p; | 1734 | ets->thread = p; |
1738 | list_add(&tmp->list, &info->thread_list); | 1735 | list_add(&ets->list, &info->thread_list); |
1739 | } | 1736 | } |
1740 | while_each_thread(g, p); | 1737 | while_each_thread(g, p); |
1741 | rcu_read_unlock(); | 1738 | rcu_read_unlock(); |
1742 | list_for_each(t, &info->thread_list) { | 1739 | list_for_each(t, &info->thread_list) { |
1743 | struct elf_thread_status *tmp; | ||
1744 | int sz; | 1740 | int sz; |
1745 | 1741 | ||
1746 | tmp = list_entry(t, struct elf_thread_status, list); | 1742 | ets = list_entry(t, struct elf_thread_status, list); |
1747 | sz = elf_dump_thread_status(signr, tmp); | 1743 | sz = elf_dump_thread_status(signr, ets); |
1748 | info->thread_status_size += sz; | 1744 | info->thread_status_size += sz; |
1749 | } | 1745 | } |
1750 | } | 1746 | } |
@@ -2000,10 +1996,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un | |||
2000 | 1996 | ||
2001 | for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { | 1997 | for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { |
2002 | struct page *page; | 1998 | struct page *page; |
2003 | struct vm_area_struct *vma; | 1999 | struct vm_area_struct *tmp_vma; |
2004 | 2000 | ||
2005 | if (get_user_pages(current, current->mm, addr, 1, 0, 1, | 2001 | if (get_user_pages(current, current->mm, addr, 1, 0, 1, |
2006 | &page, &vma) <= 0) { | 2002 | &page, &tmp_vma) <= 0) { |
2007 | DUMP_SEEK(PAGE_SIZE); | 2003 | DUMP_SEEK(PAGE_SIZE); |
2008 | } else { | 2004 | } else { |
2009 | if (page == ZERO_PAGE(0)) { | 2005 | if (page == ZERO_PAGE(0)) { |
@@ -2013,7 +2009,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file, un | |||
2013 | } | 2009 | } |
2014 | } else { | 2010 | } else { |
2015 | void *kaddr; | 2011 | void *kaddr; |
2016 | flush_cache_page(vma, addr, | 2012 | flush_cache_page(tmp_vma, addr, |
2017 | page_to_pfn(page)); | 2013 | page_to_pfn(page)); |
2018 | kaddr = kmap(page); | 2014 | kaddr = kmap(page); |
2019 | if ((size += PAGE_SIZE) > limit || | 2015 | if ((size += PAGE_SIZE) > limit || |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 32649f2a1654..ddd35d873391 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -136,8 +136,8 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, | |||
136 | 136 | ||
137 | retval = kernel_read(file, params->hdr.e_phoff, | 137 | retval = kernel_read(file, params->hdr.e_phoff, |
138 | (char *) params->phdrs, size); | 138 | (char *) params->phdrs, size); |
139 | if (retval < 0) | 139 | if (unlikely(retval != size)) |
140 | return retval; | 140 | return retval < 0 ? retval : -ENOEXEC; |
141 | 141 | ||
142 | /* determine stack size for this binary */ | 142 | /* determine stack size for this binary */ |
143 | phdr = params->phdrs; | 143 | phdr = params->phdrs; |
@@ -218,8 +218,11 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
218 | phdr->p_offset, | 218 | phdr->p_offset, |
219 | interpreter_name, | 219 | interpreter_name, |
220 | phdr->p_filesz); | 220 | phdr->p_filesz); |
221 | if (retval < 0) | 221 | if (unlikely(retval != phdr->p_filesz)) { |
222 | if (retval >= 0) | ||
223 | retval = -ENOEXEC; | ||
222 | goto error; | 224 | goto error; |
225 | } | ||
223 | 226 | ||
224 | retval = -ENOENT; | 227 | retval = -ENOENT; |
225 | if (interpreter_name[phdr->p_filesz - 1] != '\0') | 228 | if (interpreter_name[phdr->p_filesz - 1] != '\0') |
@@ -245,8 +248,11 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
245 | 248 | ||
246 | retval = kernel_read(interpreter, 0, bprm->buf, | 249 | retval = kernel_read(interpreter, 0, bprm->buf, |
247 | BINPRM_BUF_SIZE); | 250 | BINPRM_BUF_SIZE); |
248 | if (retval < 0) | 251 | if (unlikely(retval != BINPRM_BUF_SIZE)) { |
252 | if (retval >= 0) | ||
253 | retval = -ENOEXEC; | ||
249 | goto error; | 254 | goto error; |
255 | } | ||
250 | 256 | ||
251 | interp_params.hdr = *((struct elfhdr *) bprm->buf); | 257 | interp_params.hdr = *((struct elfhdr *) bprm->buf); |
252 | break; | 258 | break; |
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c index f95ae9789c91..f9c88d0c8ced 100644 --- a/fs/binfmt_em86.c +++ b/fs/binfmt_em86.c | |||
@@ -43,7 +43,7 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs) | |||
43 | return -ENOEXEC; | 43 | return -ENOEXEC; |
44 | } | 44 | } |
45 | 45 | ||
46 | bprm->sh_bang++; /* Well, the bang-shell is implicit... */ | 46 | bprm->sh_bang = 1; /* Well, the bang-shell is implicit... */ |
47 | allow_write_access(bprm->file); | 47 | allow_write_access(bprm->file); |
48 | fput(bprm->file); | 48 | fput(bprm->file); |
49 | bprm->file = NULL; | 49 | bprm->file = NULL; |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index 0498b181dd52..3b40d45a3a16 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -531,7 +531,8 @@ static int load_flat_file(struct linux_binprm * bprm, | |||
531 | DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); | 531 | DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); |
532 | 532 | ||
533 | down_write(¤t->mm->mmap_sem); | 533 | down_write(¤t->mm->mmap_sem); |
534 | textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_PRIVATE, 0); | 534 | textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, |
535 | MAP_PRIVATE|MAP_EXECUTABLE, 0); | ||
535 | up_write(¤t->mm->mmap_sem); | 536 | up_write(¤t->mm->mmap_sem); |
536 | if (!textpos || textpos >= (unsigned long) -4096) { | 537 | if (!textpos || textpos >= (unsigned long) -4096) { |
537 | if (!textpos) | 538 | if (!textpos) |
@@ -932,14 +933,8 @@ static int __init init_flat_binfmt(void) | |||
932 | return register_binfmt(&flat_format); | 933 | return register_binfmt(&flat_format); |
933 | } | 934 | } |
934 | 935 | ||
935 | static void __exit exit_flat_binfmt(void) | ||
936 | { | ||
937 | unregister_binfmt(&flat_format); | ||
938 | } | ||
939 | |||
940 | /****************************************************************************/ | 936 | /****************************************************************************/ |
941 | 937 | ||
942 | core_initcall(init_flat_binfmt); | 938 | core_initcall(init_flat_binfmt); |
943 | module_exit(exit_flat_binfmt); | ||
944 | 939 | ||
945 | /****************************************************************************/ | 940 | /****************************************************************************/ |
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index dbf0ac0523de..7191306367c5 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -115,6 +115,12 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
115 | if (!enabled) | 115 | if (!enabled) |
116 | goto _ret; | 116 | goto _ret; |
117 | 117 | ||
118 | retval = -ENOEXEC; | ||
119 | if (bprm->misc_bang) | ||
120 | goto _ret; | ||
121 | |||
122 | bprm->misc_bang = 1; | ||
123 | |||
118 | /* to keep locking time low, we copy the interpreter string */ | 124 | /* to keep locking time low, we copy the interpreter string */ |
119 | read_lock(&entries_lock); | 125 | read_lock(&entries_lock); |
120 | fmt = check_file(bprm); | 126 | fmt = check_file(bprm); |
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c index ab33939b12a7..9e3963f7ebf1 100644 --- a/fs/binfmt_script.c +++ b/fs/binfmt_script.c | |||
@@ -29,7 +29,7 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs) | |||
29 | * Sorta complicated, but hopefully it will work. -TYT | 29 | * Sorta complicated, but hopefully it will work. -TYT |
30 | */ | 30 | */ |
31 | 31 | ||
32 | bprm->sh_bang++; | 32 | bprm->sh_bang = 1; |
33 | allow_write_access(bprm->file); | 33 | allow_write_access(bprm->file); |
34 | fput(bprm->file); | 34 | fput(bprm->file); |
35 | bprm->file = NULL; | 35 | bprm->file = NULL; |
diff --git a/fs/buffer.c b/fs/buffer.c index 3db4a26adc44..189efa4efc6e 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -2211,8 +2211,8 @@ out: | |||
2211 | return err; | 2211 | return err; |
2212 | } | 2212 | } |
2213 | 2213 | ||
2214 | int cont_expand_zero(struct file *file, struct address_space *mapping, | 2214 | static int cont_expand_zero(struct file *file, struct address_space *mapping, |
2215 | loff_t pos, loff_t *bytes) | 2215 | loff_t pos, loff_t *bytes) |
2216 | { | 2216 | { |
2217 | struct inode *inode = mapping->host; | 2217 | struct inode *inode = mapping->host; |
2218 | unsigned blocksize = 1 << inode->i_blkbits; | 2218 | unsigned blocksize = 1 << inode->i_blkbits; |
@@ -2328,23 +2328,6 @@ int block_commit_write(struct page *page, unsigned from, unsigned to) | |||
2328 | return 0; | 2328 | return 0; |
2329 | } | 2329 | } |
2330 | 2330 | ||
2331 | int generic_commit_write(struct file *file, struct page *page, | ||
2332 | unsigned from, unsigned to) | ||
2333 | { | ||
2334 | struct inode *inode = page->mapping->host; | ||
2335 | loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; | ||
2336 | __block_commit_write(inode,page,from,to); | ||
2337 | /* | ||
2338 | * No need to use i_size_read() here, the i_size | ||
2339 | * cannot change under us because we hold i_mutex. | ||
2340 | */ | ||
2341 | if (pos > inode->i_size) { | ||
2342 | i_size_write(inode, pos); | ||
2343 | mark_inode_dirty(inode); | ||
2344 | } | ||
2345 | return 0; | ||
2346 | } | ||
2347 | |||
2348 | /* | 2331 | /* |
2349 | * block_page_mkwrite() is not allowed to change the file size as it gets | 2332 | * block_page_mkwrite() is not allowed to change the file size as it gets |
2350 | * called from a page fault handler when a page is first dirtied. Hence we must | 2333 | * called from a page fault handler when a page is first dirtied. Hence we must |
@@ -3315,7 +3298,6 @@ EXPORT_SYMBOL(end_buffer_write_sync); | |||
3315 | EXPORT_SYMBOL(file_fsync); | 3298 | EXPORT_SYMBOL(file_fsync); |
3316 | EXPORT_SYMBOL(fsync_bdev); | 3299 | EXPORT_SYMBOL(fsync_bdev); |
3317 | EXPORT_SYMBOL(generic_block_bmap); | 3300 | EXPORT_SYMBOL(generic_block_bmap); |
3318 | EXPORT_SYMBOL(generic_commit_write); | ||
3319 | EXPORT_SYMBOL(generic_cont_expand_simple); | 3301 | EXPORT_SYMBOL(generic_cont_expand_simple); |
3320 | EXPORT_SYMBOL(init_buffer); | 3302 | EXPORT_SYMBOL(init_buffer); |
3321 | EXPORT_SYMBOL(invalidate_bdev); | 3303 | EXPORT_SYMBOL(invalidate_bdev); |
diff --git a/fs/char_dev.c b/fs/char_dev.c index 038674aa88a7..68e510b88457 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -55,7 +55,6 @@ static struct char_device_struct { | |||
55 | unsigned int baseminor; | 55 | unsigned int baseminor; |
56 | int minorct; | 56 | int minorct; |
57 | char name[64]; | 57 | char name[64]; |
58 | struct file_operations *fops; | ||
59 | struct cdev *cdev; /* will die */ | 58 | struct cdev *cdev; /* will die */ |
60 | } *chrdevs[CHRDEV_MAJOR_HASH_SIZE]; | 59 | } *chrdevs[CHRDEV_MAJOR_HASH_SIZE]; |
61 | 60 | ||
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 0228ed06069e..cc950f69e51e 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
@@ -468,7 +468,7 @@ cifs_proc_init(void) | |||
468 | { | 468 | { |
469 | struct proc_dir_entry *pde; | 469 | struct proc_dir_entry *pde; |
470 | 470 | ||
471 | proc_fs_cifs = proc_mkdir("cifs", proc_root_fs); | 471 | proc_fs_cifs = proc_mkdir("fs/cifs", NULL); |
472 | if (proc_fs_cifs == NULL) | 472 | if (proc_fs_cifs == NULL) |
473 | return; | 473 | return; |
474 | 474 | ||
@@ -559,7 +559,7 @@ cifs_proc_clean(void) | |||
559 | remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); | 559 | remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); |
560 | remove_proc_entry("Experimental", proc_fs_cifs); | 560 | remove_proc_entry("Experimental", proc_fs_cifs); |
561 | remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); | 561 | remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); |
562 | remove_proc_entry("cifs", proc_root_fs); | 562 | remove_proc_entry("fs/cifs", NULL); |
563 | } | 563 | } |
564 | 564 | ||
565 | static int | 565 | static int |
diff --git a/fs/coda/coda_linux.c b/fs/coda/coda_linux.c index 95a54253c047..e1c854890f94 100644 --- a/fs/coda/coda_linux.c +++ b/fs/coda/coda_linux.c | |||
@@ -134,7 +134,7 @@ void coda_iattr_to_vattr(struct iattr *iattr, struct coda_vattr *vattr) | |||
134 | unsigned int valid; | 134 | unsigned int valid; |
135 | 135 | ||
136 | /* clean out */ | 136 | /* clean out */ |
137 | vattr->va_mode = (umode_t) -1; | 137 | vattr->va_mode = -1; |
138 | vattr->va_uid = (vuid_t) -1; | 138 | vattr->va_uid = (vuid_t) -1; |
139 | vattr->va_gid = (vgid_t) -1; | 139 | vattr->va_gid = (vgid_t) -1; |
140 | vattr->va_size = (off_t) -1; | 140 | vattr->va_size = (off_t) -1; |
diff --git a/fs/coda/dir.c b/fs/coda/dir.c index f89ff083079b..3d2580e00a3e 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c | |||
@@ -345,7 +345,7 @@ static int coda_symlink(struct inode *dir_inode, struct dentry *de, | |||
345 | } | 345 | } |
346 | 346 | ||
347 | /* destruction routines: unlink, rmdir */ | 347 | /* destruction routines: unlink, rmdir */ |
348 | int coda_unlink(struct inode *dir, struct dentry *de) | 348 | static int coda_unlink(struct inode *dir, struct dentry *de) |
349 | { | 349 | { |
350 | int error; | 350 | int error; |
351 | const char *name = de->d_name.name; | 351 | const char *name = de->d_name.name; |
@@ -365,7 +365,7 @@ int coda_unlink(struct inode *dir, struct dentry *de) | |||
365 | return 0; | 365 | return 0; |
366 | } | 366 | } |
367 | 367 | ||
368 | int coda_rmdir(struct inode *dir, struct dentry *de) | 368 | static int coda_rmdir(struct inode *dir, struct dentry *de) |
369 | { | 369 | { |
370 | const char *name = de->d_name.name; | 370 | const char *name = de->d_name.name; |
371 | int len = de->d_name.len; | 371 | int len = de->d_name.len; |
@@ -424,7 +424,7 @@ static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
424 | 424 | ||
425 | 425 | ||
426 | /* file operations for directories */ | 426 | /* file operations for directories */ |
427 | int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir) | 427 | static int coda_readdir(struct file *coda_file, void *buf, filldir_t filldir) |
428 | { | 428 | { |
429 | struct coda_file_info *cfi; | 429 | struct coda_file_info *cfi; |
430 | struct file *host_file; | 430 | struct file *host_file; |
diff --git a/fs/drop_caches.c b/fs/drop_caches.c index 59375efcf39d..3e5637fc3779 100644 --- a/fs/drop_caches.c +++ b/fs/drop_caches.c | |||
@@ -14,18 +14,26 @@ int sysctl_drop_caches; | |||
14 | 14 | ||
15 | static void drop_pagecache_sb(struct super_block *sb) | 15 | static void drop_pagecache_sb(struct super_block *sb) |
16 | { | 16 | { |
17 | struct inode *inode; | 17 | struct inode *inode, *toput_inode = NULL; |
18 | 18 | ||
19 | spin_lock(&inode_lock); | 19 | spin_lock(&inode_lock); |
20 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | 20 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { |
21 | if (inode->i_state & (I_FREEING|I_WILL_FREE)) | 21 | if (inode->i_state & (I_FREEING|I_WILL_FREE)) |
22 | continue; | 22 | continue; |
23 | if (inode->i_mapping->nrpages == 0) | ||
24 | continue; | ||
25 | __iget(inode); | ||
26 | spin_unlock(&inode_lock); | ||
23 | __invalidate_mapping_pages(inode->i_mapping, 0, -1, true); | 27 | __invalidate_mapping_pages(inode->i_mapping, 0, -1, true); |
28 | iput(toput_inode); | ||
29 | toput_inode = inode; | ||
30 | spin_lock(&inode_lock); | ||
24 | } | 31 | } |
25 | spin_unlock(&inode_lock); | 32 | spin_unlock(&inode_lock); |
33 | iput(toput_inode); | ||
26 | } | 34 | } |
27 | 35 | ||
28 | void drop_pagecache(void) | 36 | static void drop_pagecache(void) |
29 | { | 37 | { |
30 | struct super_block *sb; | 38 | struct super_block *sb; |
31 | 39 | ||
@@ -45,7 +53,7 @@ restart: | |||
45 | spin_unlock(&sb_lock); | 53 | spin_unlock(&sb_lock); |
46 | } | 54 | } |
47 | 55 | ||
48 | void drop_slab(void) | 56 | static void drop_slab(void) |
49 | { | 57 | { |
50 | int nr_objects; | 58 | int nr_objects; |
51 | 59 | ||
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile index 768857015516..1e34a7fd4884 100644 --- a/fs/ecryptfs/Makefile +++ b/fs/ecryptfs/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o | 5 | obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o |
6 | 6 | ||
7 | ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o debug.o | 7 | ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o miscdev.o debug.o |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index a066e109ad9c..cd62d75b2cc0 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -119,21 +119,21 @@ static int ecryptfs_calculate_md5(char *dst, | |||
119 | if (rc) { | 119 | if (rc) { |
120 | printk(KERN_ERR | 120 | printk(KERN_ERR |
121 | "%s: Error initializing crypto hash; rc = [%d]\n", | 121 | "%s: Error initializing crypto hash; rc = [%d]\n", |
122 | __FUNCTION__, rc); | 122 | __func__, rc); |
123 | goto out; | 123 | goto out; |
124 | } | 124 | } |
125 | rc = crypto_hash_update(&desc, &sg, len); | 125 | rc = crypto_hash_update(&desc, &sg, len); |
126 | if (rc) { | 126 | if (rc) { |
127 | printk(KERN_ERR | 127 | printk(KERN_ERR |
128 | "%s: Error updating crypto hash; rc = [%d]\n", | 128 | "%s: Error updating crypto hash; rc = [%d]\n", |
129 | __FUNCTION__, rc); | 129 | __func__, rc); |
130 | goto out; | 130 | goto out; |
131 | } | 131 | } |
132 | rc = crypto_hash_final(&desc, dst); | 132 | rc = crypto_hash_final(&desc, dst); |
133 | if (rc) { | 133 | if (rc) { |
134 | printk(KERN_ERR | 134 | printk(KERN_ERR |
135 | "%s: Error finalizing crypto hash; rc = [%d]\n", | 135 | "%s: Error finalizing crypto hash; rc = [%d]\n", |
136 | __FUNCTION__, rc); | 136 | __func__, rc); |
137 | goto out; | 137 | goto out; |
138 | } | 138 | } |
139 | out: | 139 | out: |
@@ -437,7 +437,7 @@ static int ecryptfs_encrypt_extent(struct page *enc_extent_page, | |||
437 | if (rc < 0) { | 437 | if (rc < 0) { |
438 | printk(KERN_ERR "%s: Error attempting to encrypt page with " | 438 | printk(KERN_ERR "%s: Error attempting to encrypt page with " |
439 | "page->index = [%ld], extent_offset = [%ld]; " | 439 | "page->index = [%ld], extent_offset = [%ld]; " |
440 | "rc = [%d]\n", __FUNCTION__, page->index, extent_offset, | 440 | "rc = [%d]\n", __func__, page->index, extent_offset, |
441 | rc); | 441 | rc); |
442 | goto out; | 442 | goto out; |
443 | } | 443 | } |
@@ -487,7 +487,7 @@ int ecryptfs_encrypt_page(struct page *page) | |||
487 | 0, PAGE_CACHE_SIZE); | 487 | 0, PAGE_CACHE_SIZE); |
488 | if (rc) | 488 | if (rc) |
489 | printk(KERN_ERR "%s: Error attempting to copy " | 489 | printk(KERN_ERR "%s: Error attempting to copy " |
490 | "page at index [%ld]\n", __FUNCTION__, | 490 | "page at index [%ld]\n", __func__, |
491 | page->index); | 491 | page->index); |
492 | goto out; | 492 | goto out; |
493 | } | 493 | } |
@@ -508,7 +508,7 @@ int ecryptfs_encrypt_page(struct page *page) | |||
508 | extent_offset); | 508 | extent_offset); |
509 | if (rc) { | 509 | if (rc) { |
510 | printk(KERN_ERR "%s: Error encrypting extent; " | 510 | printk(KERN_ERR "%s: Error encrypting extent; " |
511 | "rc = [%d]\n", __FUNCTION__, rc); | 511 | "rc = [%d]\n", __func__, rc); |
512 | goto out; | 512 | goto out; |
513 | } | 513 | } |
514 | ecryptfs_lower_offset_for_extent( | 514 | ecryptfs_lower_offset_for_extent( |
@@ -569,7 +569,7 @@ static int ecryptfs_decrypt_extent(struct page *page, | |||
569 | if (rc < 0) { | 569 | if (rc < 0) { |
570 | printk(KERN_ERR "%s: Error attempting to decrypt to page with " | 570 | printk(KERN_ERR "%s: Error attempting to decrypt to page with " |
571 | "page->index = [%ld], extent_offset = [%ld]; " | 571 | "page->index = [%ld], extent_offset = [%ld]; " |
572 | "rc = [%d]\n", __FUNCTION__, page->index, extent_offset, | 572 | "rc = [%d]\n", __func__, page->index, extent_offset, |
573 | rc); | 573 | rc); |
574 | goto out; | 574 | goto out; |
575 | } | 575 | } |
@@ -622,7 +622,7 @@ int ecryptfs_decrypt_page(struct page *page) | |||
622 | ecryptfs_inode); | 622 | ecryptfs_inode); |
623 | if (rc) | 623 | if (rc) |
624 | printk(KERN_ERR "%s: Error attempting to copy " | 624 | printk(KERN_ERR "%s: Error attempting to copy " |
625 | "page at index [%ld]\n", __FUNCTION__, | 625 | "page at index [%ld]\n", __func__, |
626 | page->index); | 626 | page->index); |
627 | goto out; | 627 | goto out; |
628 | } | 628 | } |
@@ -656,7 +656,7 @@ int ecryptfs_decrypt_page(struct page *page) | |||
656 | extent_offset); | 656 | extent_offset); |
657 | if (rc) { | 657 | if (rc) { |
658 | printk(KERN_ERR "%s: Error encrypting extent; " | 658 | printk(KERN_ERR "%s: Error encrypting extent; " |
659 | "rc = [%d]\n", __FUNCTION__, rc); | 659 | "rc = [%d]\n", __func__, rc); |
660 | goto out; | 660 | goto out; |
661 | } | 661 | } |
662 | } | 662 | } |
@@ -1215,7 +1215,7 @@ int ecryptfs_read_and_validate_header_region(char *data, | |||
1215 | ecryptfs_inode); | 1215 | ecryptfs_inode); |
1216 | if (rc) { | 1216 | if (rc) { |
1217 | printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n", | 1217 | printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n", |
1218 | __FUNCTION__, rc); | 1218 | __func__, rc); |
1219 | goto out; | 1219 | goto out; |
1220 | } | 1220 | } |
1221 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { | 1221 | if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { |
@@ -1246,7 +1246,6 @@ ecryptfs_write_header_metadata(char *virt, | |||
1246 | (*written) = 6; | 1246 | (*written) = 6; |
1247 | } | 1247 | } |
1248 | 1248 | ||
1249 | struct kmem_cache *ecryptfs_header_cache_0; | ||
1250 | struct kmem_cache *ecryptfs_header_cache_1; | 1249 | struct kmem_cache *ecryptfs_header_cache_1; |
1251 | struct kmem_cache *ecryptfs_header_cache_2; | 1250 | struct kmem_cache *ecryptfs_header_cache_2; |
1252 | 1251 | ||
@@ -1320,7 +1319,7 @@ ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, | |||
1320 | 0, crypt_stat->num_header_bytes_at_front); | 1319 | 0, crypt_stat->num_header_bytes_at_front); |
1321 | if (rc) | 1320 | if (rc) |
1322 | printk(KERN_ERR "%s: Error attempting to write header " | 1321 | printk(KERN_ERR "%s: Error attempting to write header " |
1323 | "information to lower file; rc = [%d]\n", __FUNCTION__, | 1322 | "information to lower file; rc = [%d]\n", __func__, |
1324 | rc); | 1323 | rc); |
1325 | return rc; | 1324 | return rc; |
1326 | } | 1325 | } |
@@ -1365,14 +1364,14 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
1365 | } | 1364 | } |
1366 | } else { | 1365 | } else { |
1367 | printk(KERN_WARNING "%s: Encrypted flag not set\n", | 1366 | printk(KERN_WARNING "%s: Encrypted flag not set\n", |
1368 | __FUNCTION__); | 1367 | __func__); |
1369 | rc = -EINVAL; | 1368 | rc = -EINVAL; |
1370 | goto out; | 1369 | goto out; |
1371 | } | 1370 | } |
1372 | /* Released in this function */ | 1371 | /* Released in this function */ |
1373 | virt = kzalloc(crypt_stat->num_header_bytes_at_front, GFP_KERNEL); | 1372 | virt = kzalloc(crypt_stat->num_header_bytes_at_front, GFP_KERNEL); |
1374 | if (!virt) { | 1373 | if (!virt) { |
1375 | printk(KERN_ERR "%s: Out of memory\n", __FUNCTION__); | 1374 | printk(KERN_ERR "%s: Out of memory\n", __func__); |
1376 | rc = -ENOMEM; | 1375 | rc = -ENOMEM; |
1377 | goto out; | 1376 | goto out; |
1378 | } | 1377 | } |
@@ -1380,7 +1379,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
1380 | ecryptfs_dentry); | 1379 | ecryptfs_dentry); |
1381 | if (unlikely(rc)) { | 1380 | if (unlikely(rc)) { |
1382 | printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", | 1381 | printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", |
1383 | __FUNCTION__, rc); | 1382 | __func__, rc); |
1384 | goto out_free; | 1383 | goto out_free; |
1385 | } | 1384 | } |
1386 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 1385 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
@@ -1391,7 +1390,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
1391 | ecryptfs_dentry, virt); | 1390 | ecryptfs_dentry, virt); |
1392 | if (rc) { | 1391 | if (rc) { |
1393 | printk(KERN_ERR "%s: Error writing metadata out to lower file; " | 1392 | printk(KERN_ERR "%s: Error writing metadata out to lower file; " |
1394 | "rc = [%d]\n", __FUNCTION__, rc); | 1393 | "rc = [%d]\n", __func__, rc); |
1395 | goto out_free; | 1394 | goto out_free; |
1396 | } | 1395 | } |
1397 | out_free: | 1396 | out_free: |
@@ -1585,7 +1584,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry) | |||
1585 | if (!page_virt) { | 1584 | if (!page_virt) { |
1586 | rc = -ENOMEM; | 1585 | rc = -ENOMEM; |
1587 | printk(KERN_ERR "%s: Unable to allocate page_virt\n", | 1586 | printk(KERN_ERR "%s: Unable to allocate page_virt\n", |
1588 | __FUNCTION__); | 1587 | __func__); |
1589 | goto out; | 1588 | goto out; |
1590 | } | 1589 | } |
1591 | rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size, | 1590 | rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size, |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 5007f788da01..951ee33a022d 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 1997-2003 Erez Zadok | 5 | * Copyright (C) 1997-2003 Erez Zadok |
6 | * Copyright (C) 2001-2003 Stony Brook University | 6 | * Copyright (C) 2001-2003 Stony Brook University |
7 | * Copyright (C) 2004-2007 International Business Machines Corp. | 7 | * Copyright (C) 2004-2008 International Business Machines Corp. |
8 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> | 8 | * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com> |
9 | * Trevor S. Highland <trevor.highland@gmail.com> | 9 | * Trevor S. Highland <trevor.highland@gmail.com> |
10 | * Tyler Hicks <tyhicks@ou.edu> | 10 | * Tyler Hicks <tyhicks@ou.edu> |
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/namei.h> | 34 | #include <linux/namei.h> |
35 | #include <linux/scatterlist.h> | 35 | #include <linux/scatterlist.h> |
36 | #include <linux/hash.h> | 36 | #include <linux/hash.h> |
37 | #include <linux/nsproxy.h> | ||
37 | 38 | ||
38 | /* Version verification for shared data structures w/ userspace */ | 39 | /* Version verification for shared data structures w/ userspace */ |
39 | #define ECRYPTFS_VERSION_MAJOR 0x00 | 40 | #define ECRYPTFS_VERSION_MAJOR 0x00 |
@@ -49,11 +50,13 @@ | |||
49 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 | 50 | #define ECRYPTFS_VERSIONING_POLICY 0x00000008 |
50 | #define ECRYPTFS_VERSIONING_XATTR 0x00000010 | 51 | #define ECRYPTFS_VERSIONING_XATTR 0x00000010 |
51 | #define ECRYPTFS_VERSIONING_MULTKEY 0x00000020 | 52 | #define ECRYPTFS_VERSIONING_MULTKEY 0x00000020 |
53 | #define ECRYPTFS_VERSIONING_DEVMISC 0x00000040 | ||
52 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ | 54 | #define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ |
53 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ | 55 | | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ |
54 | | ECRYPTFS_VERSIONING_PUBKEY \ | 56 | | ECRYPTFS_VERSIONING_PUBKEY \ |
55 | | ECRYPTFS_VERSIONING_XATTR \ | 57 | | ECRYPTFS_VERSIONING_XATTR \ |
56 | | ECRYPTFS_VERSIONING_MULTKEY) | 58 | | ECRYPTFS_VERSIONING_MULTKEY \ |
59 | | ECRYPTFS_VERSIONING_DEVMISC) | ||
57 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 | 60 | #define ECRYPTFS_MAX_PASSWORD_LENGTH 64 |
58 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH | 61 | #define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH |
59 | #define ECRYPTFS_SALT_SIZE 8 | 62 | #define ECRYPTFS_SALT_SIZE 8 |
@@ -73,17 +76,14 @@ | |||
73 | #define ECRYPTFS_DEFAULT_MSG_CTX_ELEMS 32 | 76 | #define ECRYPTFS_DEFAULT_MSG_CTX_ELEMS 32 |
74 | #define ECRYPTFS_DEFAULT_SEND_TIMEOUT HZ | 77 | #define ECRYPTFS_DEFAULT_SEND_TIMEOUT HZ |
75 | #define ECRYPTFS_MAX_MSG_CTX_TTL (HZ*3) | 78 | #define ECRYPTFS_MAX_MSG_CTX_TTL (HZ*3) |
76 | #define ECRYPTFS_NLMSG_HELO 100 | ||
77 | #define ECRYPTFS_NLMSG_QUIT 101 | ||
78 | #define ECRYPTFS_NLMSG_REQUEST 102 | ||
79 | #define ECRYPTFS_NLMSG_RESPONSE 103 | ||
80 | #define ECRYPTFS_MAX_PKI_NAME_BYTES 16 | 79 | #define ECRYPTFS_MAX_PKI_NAME_BYTES 16 |
81 | #define ECRYPTFS_DEFAULT_NUM_USERS 4 | 80 | #define ECRYPTFS_DEFAULT_NUM_USERS 4 |
82 | #define ECRYPTFS_MAX_NUM_USERS 32768 | 81 | #define ECRYPTFS_MAX_NUM_USERS 32768 |
83 | #define ECRYPTFS_TRANSPORT_NETLINK 0 | 82 | #define ECRYPTFS_TRANSPORT_NETLINK 0 |
84 | #define ECRYPTFS_TRANSPORT_CONNECTOR 1 | 83 | #define ECRYPTFS_TRANSPORT_CONNECTOR 1 |
85 | #define ECRYPTFS_TRANSPORT_RELAYFS 2 | 84 | #define ECRYPTFS_TRANSPORT_RELAYFS 2 |
86 | #define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_NETLINK | 85 | #define ECRYPTFS_TRANSPORT_MISCDEV 3 |
86 | #define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_MISCDEV | ||
87 | #define ECRYPTFS_XATTR_NAME "user.ecryptfs" | 87 | #define ECRYPTFS_XATTR_NAME "user.ecryptfs" |
88 | 88 | ||
89 | #define RFC2440_CIPHER_DES3_EDE 0x02 | 89 | #define RFC2440_CIPHER_DES3_EDE 0x02 |
@@ -366,32 +366,63 @@ struct ecryptfs_auth_tok_list_item { | |||
366 | }; | 366 | }; |
367 | 367 | ||
368 | struct ecryptfs_message { | 368 | struct ecryptfs_message { |
369 | /* Can never be greater than ecryptfs_message_buf_len */ | ||
370 | /* Used to find the parent msg_ctx */ | ||
371 | /* Inherits from msg_ctx->index */ | ||
369 | u32 index; | 372 | u32 index; |
370 | u32 data_len; | 373 | u32 data_len; |
371 | u8 data[]; | 374 | u8 data[]; |
372 | }; | 375 | }; |
373 | 376 | ||
374 | struct ecryptfs_msg_ctx { | 377 | struct ecryptfs_msg_ctx { |
375 | #define ECRYPTFS_MSG_CTX_STATE_FREE 0x0001 | 378 | #define ECRYPTFS_MSG_CTX_STATE_FREE 0x01 |
376 | #define ECRYPTFS_MSG_CTX_STATE_PENDING 0x0002 | 379 | #define ECRYPTFS_MSG_CTX_STATE_PENDING 0x02 |
377 | #define ECRYPTFS_MSG_CTX_STATE_DONE 0x0003 | 380 | #define ECRYPTFS_MSG_CTX_STATE_DONE 0x03 |
378 | u32 state; | 381 | #define ECRYPTFS_MSG_CTX_STATE_NO_REPLY 0x04 |
379 | unsigned int index; | 382 | u8 state; |
380 | unsigned int counter; | 383 | #define ECRYPTFS_MSG_HELO 100 |
384 | #define ECRYPTFS_MSG_QUIT 101 | ||
385 | #define ECRYPTFS_MSG_REQUEST 102 | ||
386 | #define ECRYPTFS_MSG_RESPONSE 103 | ||
387 | u8 type; | ||
388 | u32 index; | ||
389 | /* Counter converts to a sequence number. Each message sent | ||
390 | * out for which we expect a response has an associated | ||
391 | * sequence number. The response must have the same sequence | ||
392 | * number as the counter for the msg_stc for the message to be | ||
393 | * valid. */ | ||
394 | u32 counter; | ||
395 | size_t msg_size; | ||
381 | struct ecryptfs_message *msg; | 396 | struct ecryptfs_message *msg; |
382 | struct task_struct *task; | 397 | struct task_struct *task; |
383 | struct list_head node; | 398 | struct list_head node; |
399 | struct list_head daemon_out_list; | ||
384 | struct mutex mux; | 400 | struct mutex mux; |
385 | }; | 401 | }; |
386 | 402 | ||
387 | extern unsigned int ecryptfs_transport; | 403 | extern unsigned int ecryptfs_transport; |
388 | 404 | ||
389 | struct ecryptfs_daemon_id { | 405 | struct ecryptfs_daemon; |
390 | pid_t pid; | 406 | |
391 | uid_t uid; | 407 | struct ecryptfs_daemon { |
392 | struct hlist_node id_chain; | 408 | #define ECRYPTFS_DAEMON_IN_READ 0x00000001 |
409 | #define ECRYPTFS_DAEMON_IN_POLL 0x00000002 | ||
410 | #define ECRYPTFS_DAEMON_ZOMBIE 0x00000004 | ||
411 | #define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008 | ||
412 | u32 flags; | ||
413 | u32 num_queued_msg_ctx; | ||
414 | struct pid *pid; | ||
415 | uid_t euid; | ||
416 | struct user_namespace *user_ns; | ||
417 | struct task_struct *task; | ||
418 | struct mutex mux; | ||
419 | struct list_head msg_ctx_out_queue; | ||
420 | wait_queue_head_t wait; | ||
421 | struct hlist_node euid_chain; | ||
393 | }; | 422 | }; |
394 | 423 | ||
424 | extern struct mutex ecryptfs_daemon_hash_mux; | ||
425 | |||
395 | static inline struct ecryptfs_file_info * | 426 | static inline struct ecryptfs_file_info * |
396 | ecryptfs_file_to_private(struct file *file) | 427 | ecryptfs_file_to_private(struct file *file) |
397 | { | 428 | { |
@@ -500,7 +531,7 @@ ecryptfs_set_dentry_lower_mnt(struct dentry *dentry, struct vfsmount *lower_mnt) | |||
500 | } | 531 | } |
501 | 532 | ||
502 | #define ecryptfs_printk(type, fmt, arg...) \ | 533 | #define ecryptfs_printk(type, fmt, arg...) \ |
503 | __ecryptfs_printk(type "%s: " fmt, __FUNCTION__, ## arg); | 534 | __ecryptfs_printk(type "%s: " fmt, __func__, ## arg); |
504 | void __ecryptfs_printk(const char *fmt, ...); | 535 | void __ecryptfs_printk(const char *fmt, ...); |
505 | 536 | ||
506 | extern const struct file_operations ecryptfs_main_fops; | 537 | extern const struct file_operations ecryptfs_main_fops; |
@@ -581,10 +612,13 @@ int | |||
581 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 612 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
582 | size_t size, int flags); | 613 | size_t size, int flags); |
583 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); | 614 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); |
584 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); | 615 | int ecryptfs_process_helo(unsigned int transport, uid_t euid, |
585 | int ecryptfs_process_quit(uid_t uid, pid_t pid); | 616 | struct user_namespace *user_ns, struct pid *pid); |
586 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, | 617 | int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, |
587 | pid_t pid, u32 seq); | 618 | struct pid *pid); |
619 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | ||
620 | struct user_namespace *user_ns, struct pid *pid, | ||
621 | u32 seq); | ||
588 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | 622 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, |
589 | struct ecryptfs_msg_ctx **msg_ctx); | 623 | struct ecryptfs_msg_ctx **msg_ctx); |
590 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | 624 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, |
@@ -593,14 +627,14 @@ int ecryptfs_init_messaging(unsigned int transport); | |||
593 | void ecryptfs_release_messaging(unsigned int transport); | 627 | void ecryptfs_release_messaging(unsigned int transport); |
594 | 628 | ||
595 | int ecryptfs_send_netlink(char *data, int data_len, | 629 | int ecryptfs_send_netlink(char *data, int data_len, |
596 | struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type, | 630 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, |
597 | u16 msg_flags, pid_t daemon_pid); | 631 | u16 msg_flags, struct pid *daemon_pid); |
598 | int ecryptfs_init_netlink(void); | 632 | int ecryptfs_init_netlink(void); |
599 | void ecryptfs_release_netlink(void); | 633 | void ecryptfs_release_netlink(void); |
600 | 634 | ||
601 | int ecryptfs_send_connector(char *data, int data_len, | 635 | int ecryptfs_send_connector(char *data, int data_len, |
602 | struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type, | 636 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, |
603 | u16 msg_flags, pid_t daemon_pid); | 637 | u16 msg_flags, struct pid *daemon_pid); |
604 | int ecryptfs_init_connector(void); | 638 | int ecryptfs_init_connector(void); |
605 | void ecryptfs_release_connector(void); | 639 | void ecryptfs_release_connector(void); |
606 | void | 640 | void |
@@ -642,5 +676,21 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
642 | size_t offset_in_page, size_t size, | 676 | size_t offset_in_page, size_t size, |
643 | struct inode *ecryptfs_inode); | 677 | struct inode *ecryptfs_inode); |
644 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); | 678 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); |
679 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); | ||
680 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, | ||
681 | struct user_namespace *user_ns); | ||
682 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, | ||
683 | size_t *length_size); | ||
684 | int ecryptfs_write_packet_length(char *dest, size_t size, | ||
685 | size_t *packet_size_length); | ||
686 | int ecryptfs_init_ecryptfs_miscdev(void); | ||
687 | void ecryptfs_destroy_ecryptfs_miscdev(void); | ||
688 | int ecryptfs_send_miscdev(char *data, size_t data_size, | ||
689 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, | ||
690 | u16 msg_flags, struct ecryptfs_daemon *daemon); | ||
691 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); | ||
692 | int | ||
693 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | ||
694 | struct user_namespace *user_ns, struct pid *pid); | ||
645 | 695 | ||
646 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 696 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 2b8f5ed4adea..2258b8f654a6 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -195,7 +195,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
195 | file, ecryptfs_inode_to_private(inode)->lower_file); | 195 | file, ecryptfs_inode_to_private(inode)->lower_file); |
196 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { | 196 | if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { |
197 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); | 197 | ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); |
198 | mutex_lock(&crypt_stat->cs_mutex); | ||
198 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 199 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
200 | mutex_unlock(&crypt_stat->cs_mutex); | ||
199 | rc = 0; | 201 | rc = 0; |
200 | goto out; | 202 | goto out; |
201 | } | 203 | } |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index e23861152101..0a1397335a8e 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -111,7 +111,7 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
111 | 111 | ||
112 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 112 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
113 | lower_dir_dentry = lock_parent(lower_dentry); | 113 | lower_dir_dentry = lock_parent(lower_dentry); |
114 | if (unlikely(IS_ERR(lower_dir_dentry))) { | 114 | if (IS_ERR(lower_dir_dentry)) { |
115 | ecryptfs_printk(KERN_ERR, "Error locking directory of " | 115 | ecryptfs_printk(KERN_ERR, "Error locking directory of " |
116 | "dentry\n"); | 116 | "dentry\n"); |
117 | rc = PTR_ERR(lower_dir_dentry); | 117 | rc = PTR_ERR(lower_dir_dentry); |
@@ -121,7 +121,7 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
121 | ecryptfs_dentry, mode, nd); | 121 | ecryptfs_dentry, mode, nd); |
122 | if (rc) { | 122 | if (rc) { |
123 | printk(KERN_ERR "%s: Failure to create dentry in lower fs; " | 123 | printk(KERN_ERR "%s: Failure to create dentry in lower fs; " |
124 | "rc = [%d]\n", __FUNCTION__, rc); | 124 | "rc = [%d]\n", __func__, rc); |
125 | goto out_lock; | 125 | goto out_lock; |
126 | } | 126 | } |
127 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, | 127 | rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, |
@@ -908,7 +908,9 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
908 | if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) | 908 | if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) |
909 | ia->ia_valid &= ~ATTR_MODE; | 909 | ia->ia_valid &= ~ATTR_MODE; |
910 | 910 | ||
911 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
911 | rc = notify_change(lower_dentry, ia); | 912 | rc = notify_change(lower_dentry, ia); |
913 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
912 | out: | 914 | out: |
913 | fsstack_copy_attr_all(inode, lower_inode, NULL); | 915 | fsstack_copy_attr_all(inode, lower_inode, NULL); |
914 | return rc; | 916 | return rc; |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 682b1b2482c2..e82b457180be 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -65,7 +65,7 @@ static int process_request_key_err(long err_code) | |||
65 | } | 65 | } |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * parse_packet_length | 68 | * ecryptfs_parse_packet_length |
69 | * @data: Pointer to memory containing length at offset | 69 | * @data: Pointer to memory containing length at offset |
70 | * @size: This function writes the decoded size to this memory | 70 | * @size: This function writes the decoded size to this memory |
71 | * address; zero on error | 71 | * address; zero on error |
@@ -73,8 +73,8 @@ static int process_request_key_err(long err_code) | |||
73 | * | 73 | * |
74 | * Returns zero on success; non-zero on error | 74 | * Returns zero on success; non-zero on error |
75 | */ | 75 | */ |
76 | static int parse_packet_length(unsigned char *data, size_t *size, | 76 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, |
77 | size_t *length_size) | 77 | size_t *length_size) |
78 | { | 78 | { |
79 | int rc = 0; | 79 | int rc = 0; |
80 | 80 | ||
@@ -105,7 +105,7 @@ out: | |||
105 | } | 105 | } |
106 | 106 | ||
107 | /** | 107 | /** |
108 | * write_packet_length | 108 | * ecryptfs_write_packet_length |
109 | * @dest: The byte array target into which to write the length. Must | 109 | * @dest: The byte array target into which to write the length. Must |
110 | * have at least 5 bytes allocated. | 110 | * have at least 5 bytes allocated. |
111 | * @size: The length to write. | 111 | * @size: The length to write. |
@@ -114,8 +114,8 @@ out: | |||
114 | * | 114 | * |
115 | * Returns zero on success; non-zero on error. | 115 | * Returns zero on success; non-zero on error. |
116 | */ | 116 | */ |
117 | static int write_packet_length(char *dest, size_t size, | 117 | int ecryptfs_write_packet_length(char *dest, size_t size, |
118 | size_t *packet_size_length) | 118 | size_t *packet_size_length) |
119 | { | 119 | { |
120 | int rc = 0; | 120 | int rc = 0; |
121 | 121 | ||
@@ -162,8 +162,8 @@ write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key, | |||
162 | goto out; | 162 | goto out; |
163 | } | 163 | } |
164 | message[i++] = ECRYPTFS_TAG_64_PACKET_TYPE; | 164 | message[i++] = ECRYPTFS_TAG_64_PACKET_TYPE; |
165 | rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | 165 | rc = ecryptfs_write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, |
166 | &packet_size_len); | 166 | &packet_size_len); |
167 | if (rc) { | 167 | if (rc) { |
168 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | 168 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " |
169 | "header; cannot generate packet length\n"); | 169 | "header; cannot generate packet length\n"); |
@@ -172,8 +172,9 @@ write_tag_64_packet(char *signature, struct ecryptfs_session_key *session_key, | |||
172 | i += packet_size_len; | 172 | i += packet_size_len; |
173 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | 173 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); |
174 | i += ECRYPTFS_SIG_SIZE_HEX; | 174 | i += ECRYPTFS_SIG_SIZE_HEX; |
175 | rc = write_packet_length(&message[i], session_key->encrypted_key_size, | 175 | rc = ecryptfs_write_packet_length(&message[i], |
176 | &packet_size_len); | 176 | session_key->encrypted_key_size, |
177 | &packet_size_len); | ||
177 | if (rc) { | 178 | if (rc) { |
178 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " | 179 | ecryptfs_printk(KERN_ERR, "Error generating tag 64 packet " |
179 | "header; cannot generate packet length\n"); | 180 | "header; cannot generate packet length\n"); |
@@ -225,7 +226,7 @@ parse_tag_65_packet(struct ecryptfs_session_key *session_key, u8 *cipher_code, | |||
225 | rc = -EIO; | 226 | rc = -EIO; |
226 | goto out; | 227 | goto out; |
227 | } | 228 | } |
228 | rc = parse_packet_length(&data[i], &m_size, &data_len); | 229 | rc = ecryptfs_parse_packet_length(&data[i], &m_size, &data_len); |
229 | if (rc) { | 230 | if (rc) { |
230 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | 231 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " |
231 | "rc = [%d]\n", rc); | 232 | "rc = [%d]\n", rc); |
@@ -304,8 +305,8 @@ write_tag_66_packet(char *signature, u8 cipher_code, | |||
304 | goto out; | 305 | goto out; |
305 | } | 306 | } |
306 | message[i++] = ECRYPTFS_TAG_66_PACKET_TYPE; | 307 | message[i++] = ECRYPTFS_TAG_66_PACKET_TYPE; |
307 | rc = write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, | 308 | rc = ecryptfs_write_packet_length(&message[i], ECRYPTFS_SIG_SIZE_HEX, |
308 | &packet_size_len); | 309 | &packet_size_len); |
309 | if (rc) { | 310 | if (rc) { |
310 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | 311 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " |
311 | "header; cannot generate packet length\n"); | 312 | "header; cannot generate packet length\n"); |
@@ -315,8 +316,8 @@ write_tag_66_packet(char *signature, u8 cipher_code, | |||
315 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); | 316 | memcpy(&message[i], signature, ECRYPTFS_SIG_SIZE_HEX); |
316 | i += ECRYPTFS_SIG_SIZE_HEX; | 317 | i += ECRYPTFS_SIG_SIZE_HEX; |
317 | /* The encrypted key includes 1 byte cipher code and 2 byte checksum */ | 318 | /* The encrypted key includes 1 byte cipher code and 2 byte checksum */ |
318 | rc = write_packet_length(&message[i], crypt_stat->key_size + 3, | 319 | rc = ecryptfs_write_packet_length(&message[i], crypt_stat->key_size + 3, |
319 | &packet_size_len); | 320 | &packet_size_len); |
320 | if (rc) { | 321 | if (rc) { |
321 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " | 322 | ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet " |
322 | "header; cannot generate packet length\n"); | 323 | "header; cannot generate packet length\n"); |
@@ -357,20 +358,25 @@ parse_tag_67_packet(struct ecryptfs_key_record *key_rec, | |||
357 | /* verify that everything through the encrypted FEK size is present */ | 358 | /* verify that everything through the encrypted FEK size is present */ |
358 | if (message_len < 4) { | 359 | if (message_len < 4) { |
359 | rc = -EIO; | 360 | rc = -EIO; |
361 | printk(KERN_ERR "%s: message_len is [%Zd]; minimum acceptable " | ||
362 | "message length is [%d]\n", __func__, message_len, 4); | ||
360 | goto out; | 363 | goto out; |
361 | } | 364 | } |
362 | if (data[i++] != ECRYPTFS_TAG_67_PACKET_TYPE) { | 365 | if (data[i++] != ECRYPTFS_TAG_67_PACKET_TYPE) { |
363 | ecryptfs_printk(KERN_ERR, "Type should be ECRYPTFS_TAG_67\n"); | ||
364 | rc = -EIO; | 366 | rc = -EIO; |
367 | printk(KERN_ERR "%s: Type should be ECRYPTFS_TAG_67\n", | ||
368 | __func__); | ||
365 | goto out; | 369 | goto out; |
366 | } | 370 | } |
367 | if (data[i++]) { | 371 | if (data[i++]) { |
368 | ecryptfs_printk(KERN_ERR, "Status indicator has non zero value" | ||
369 | " [%d]\n", data[i-1]); | ||
370 | rc = -EIO; | 372 | rc = -EIO; |
373 | printk(KERN_ERR "%s: Status indicator has non zero " | ||
374 | "value [%d]\n", __func__, data[i-1]); | ||
375 | |||
371 | goto out; | 376 | goto out; |
372 | } | 377 | } |
373 | rc = parse_packet_length(&data[i], &key_rec->enc_key_size, &data_len); | 378 | rc = ecryptfs_parse_packet_length(&data[i], &key_rec->enc_key_size, |
379 | &data_len); | ||
374 | if (rc) { | 380 | if (rc) { |
375 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " | 381 | ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " |
376 | "rc = [%d]\n", rc); | 382 | "rc = [%d]\n", rc); |
@@ -378,17 +384,17 @@ parse_tag_67_packet(struct ecryptfs_key_record *key_rec, | |||
378 | } | 384 | } |
379 | i += data_len; | 385 | i += data_len; |
380 | if (message_len < (i + key_rec->enc_key_size)) { | 386 | if (message_len < (i + key_rec->enc_key_size)) { |
381 | ecryptfs_printk(KERN_ERR, "message_len [%d]; max len is [%d]\n", | ||
382 | message_len, (i + key_rec->enc_key_size)); | ||
383 | rc = -EIO; | 387 | rc = -EIO; |
388 | printk(KERN_ERR "%s: message_len [%Zd]; max len is [%Zd]\n", | ||
389 | __func__, message_len, (i + key_rec->enc_key_size)); | ||
384 | goto out; | 390 | goto out; |
385 | } | 391 | } |
386 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { | 392 | if (key_rec->enc_key_size > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { |
387 | ecryptfs_printk(KERN_ERR, "Encrypted key_size [%d] larger than " | ||
388 | "the maximum key size [%d]\n", | ||
389 | key_rec->enc_key_size, | ||
390 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | ||
391 | rc = -EIO; | 393 | rc = -EIO; |
394 | printk(KERN_ERR "%s: Encrypted key_size [%Zd] larger than " | ||
395 | "the maximum key size [%d]\n", __func__, | ||
396 | key_rec->enc_key_size, | ||
397 | ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES); | ||
392 | goto out; | 398 | goto out; |
393 | } | 399 | } |
394 | memcpy(key_rec->enc_key, &data[i], key_rec->enc_key_size); | 400 | memcpy(key_rec->enc_key, &data[i], key_rec->enc_key_size); |
@@ -445,7 +451,7 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, | |||
445 | rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key), | 451 | rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key), |
446 | &netlink_message, &netlink_message_length); | 452 | &netlink_message, &netlink_message_length); |
447 | if (rc) { | 453 | if (rc) { |
448 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet"); | 454 | ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet\n"); |
449 | goto out; | 455 | goto out; |
450 | } | 456 | } |
451 | rc = ecryptfs_send_message(ecryptfs_transport, netlink_message, | 457 | rc = ecryptfs_send_message(ecryptfs_transport, netlink_message, |
@@ -570,8 +576,8 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
570 | goto out; | 576 | goto out; |
571 | } | 577 | } |
572 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | 578 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; |
573 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | 579 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, |
574 | &length_size); | 580 | &length_size); |
575 | if (rc) { | 581 | if (rc) { |
576 | printk(KERN_WARNING "Error parsing packet length; " | 582 | printk(KERN_WARNING "Error parsing packet length; " |
577 | "rc = [%d]\n", rc); | 583 | "rc = [%d]\n", rc); |
@@ -704,8 +710,8 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, | |||
704 | goto out; | 710 | goto out; |
705 | } | 711 | } |
706 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; | 712 | (*new_auth_tok) = &auth_tok_list_item->auth_tok; |
707 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | 713 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, |
708 | &length_size); | 714 | &length_size); |
709 | if (rc) { | 715 | if (rc) { |
710 | printk(KERN_WARNING "Error parsing packet length; rc = [%d]\n", | 716 | printk(KERN_WARNING "Error parsing packet length; rc = [%d]\n", |
711 | rc); | 717 | rc); |
@@ -852,8 +858,8 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents, | |||
852 | rc = -EINVAL; | 858 | rc = -EINVAL; |
853 | goto out; | 859 | goto out; |
854 | } | 860 | } |
855 | rc = parse_packet_length(&data[(*packet_size)], &body_size, | 861 | rc = ecryptfs_parse_packet_length(&data[(*packet_size)], &body_size, |
856 | &length_size); | 862 | &length_size); |
857 | if (rc) { | 863 | if (rc) { |
858 | printk(KERN_WARNING "Invalid tag 11 packet format\n"); | 864 | printk(KERN_WARNING "Invalid tag 11 packet format\n"); |
859 | goto out; | 865 | goto out; |
@@ -1405,8 +1411,8 @@ write_tag_1_packet(char *dest, size_t *remaining_bytes, | |||
1405 | auth_tok->token.private_key.key_size; | 1411 | auth_tok->token.private_key.key_size; |
1406 | rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec); | 1412 | rc = pki_encrypt_session_key(auth_tok, crypt_stat, key_rec); |
1407 | if (rc) { | 1413 | if (rc) { |
1408 | ecryptfs_printk(KERN_ERR, "Failed to encrypt session key " | 1414 | printk(KERN_ERR "Failed to encrypt session key via a key " |
1409 | "via a pki"); | 1415 | "module; rc = [%d]\n", rc); |
1410 | goto out; | 1416 | goto out; |
1411 | } | 1417 | } |
1412 | if (ecryptfs_verbosity > 0) { | 1418 | if (ecryptfs_verbosity > 0) { |
@@ -1430,8 +1436,9 @@ encrypted_session_key_set: | |||
1430 | goto out; | 1436 | goto out; |
1431 | } | 1437 | } |
1432 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; | 1438 | dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; |
1433 | rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4), | 1439 | rc = ecryptfs_write_packet_length(&dest[(*packet_size)], |
1434 | &packet_size_length); | 1440 | (max_packet_size - 4), |
1441 | &packet_size_length); | ||
1435 | if (rc) { | 1442 | if (rc) { |
1436 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " | 1443 | ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " |
1437 | "header; cannot generate packet length\n"); | 1444 | "header; cannot generate packet length\n"); |
@@ -1489,8 +1496,9 @@ write_tag_11_packet(char *dest, size_t *remaining_bytes, char *contents, | |||
1489 | goto out; | 1496 | goto out; |
1490 | } | 1497 | } |
1491 | dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE; | 1498 | dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE; |
1492 | rc = write_packet_length(&dest[(*packet_length)], | 1499 | rc = ecryptfs_write_packet_length(&dest[(*packet_length)], |
1493 | (max_packet_size - 4), &packet_size_length); | 1500 | (max_packet_size - 4), |
1501 | &packet_size_length); | ||
1494 | if (rc) { | 1502 | if (rc) { |
1495 | printk(KERN_ERR "Error generating tag 11 packet header; cannot " | 1503 | printk(KERN_ERR "Error generating tag 11 packet header; cannot " |
1496 | "generate packet length. rc = [%d]\n", rc); | 1504 | "generate packet length. rc = [%d]\n", rc); |
@@ -1682,8 +1690,9 @@ encrypted_session_key_set: | |||
1682 | dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE; | 1690 | dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE; |
1683 | /* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3) | 1691 | /* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3) |
1684 | * to get the number of octets in the actual Tag 3 packet */ | 1692 | * to get the number of octets in the actual Tag 3 packet */ |
1685 | rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4), | 1693 | rc = ecryptfs_write_packet_length(&dest[(*packet_size)], |
1686 | &packet_size_length); | 1694 | (max_packet_size - 4), |
1695 | &packet_size_length); | ||
1687 | if (rc) { | 1696 | if (rc) { |
1688 | printk(KERN_ERR "Error generating tag 3 packet header; cannot " | 1697 | printk(KERN_ERR "Error generating tag 3 packet header; cannot " |
1689 | "generate packet length. rc = [%d]\n", rc); | 1698 | "generate packet length. rc = [%d]\n", rc); |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index d25ac9500a92..d603631601eb 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -219,7 +219,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry, | |||
219 | if (rc) { | 219 | if (rc) { |
220 | printk(KERN_ERR "%s: Error attempting to initialize the " | 220 | printk(KERN_ERR "%s: Error attempting to initialize the " |
221 | "persistent file for the dentry with name [%s]; " | 221 | "persistent file for the dentry with name [%s]; " |
222 | "rc = [%d]\n", __FUNCTION__, dentry->d_name.name, rc); | 222 | "rc = [%d]\n", __func__, dentry->d_name.name, rc); |
223 | goto out; | 223 | goto out; |
224 | } | 224 | } |
225 | out: | 225 | out: |
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index 9cc2aec27b0d..1b5c20058acb 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /** | 1 | /** |
2 | * eCryptfs: Linux filesystem encryption layer | 2 | * eCryptfs: Linux filesystem encryption layer |
3 | * | 3 | * |
4 | * Copyright (C) 2004-2006 International Business Machines Corp. | 4 | * Copyright (C) 2004-2008 International Business Machines Corp. |
5 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | 5 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> |
6 | * Tyler Hicks <tyhicks@ou.edu> | 6 | * Tyler Hicks <tyhicks@ou.edu> |
7 | * | 7 | * |
@@ -20,19 +20,21 @@ | |||
20 | * 02111-1307, USA. | 20 | * 02111-1307, USA. |
21 | */ | 21 | */ |
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/user_namespace.h> | ||
24 | #include <linux/nsproxy.h> | ||
23 | #include "ecryptfs_kernel.h" | 25 | #include "ecryptfs_kernel.h" |
24 | 26 | ||
25 | static LIST_HEAD(ecryptfs_msg_ctx_free_list); | 27 | static LIST_HEAD(ecryptfs_msg_ctx_free_list); |
26 | static LIST_HEAD(ecryptfs_msg_ctx_alloc_list); | 28 | static LIST_HEAD(ecryptfs_msg_ctx_alloc_list); |
27 | static struct mutex ecryptfs_msg_ctx_lists_mux; | 29 | static struct mutex ecryptfs_msg_ctx_lists_mux; |
28 | 30 | ||
29 | static struct hlist_head *ecryptfs_daemon_id_hash; | 31 | static struct hlist_head *ecryptfs_daemon_hash; |
30 | static struct mutex ecryptfs_daemon_id_hash_mux; | 32 | struct mutex ecryptfs_daemon_hash_mux; |
31 | static int ecryptfs_hash_buckets; | 33 | static int ecryptfs_hash_buckets; |
32 | #define ecryptfs_uid_hash(uid) \ | 34 | #define ecryptfs_uid_hash(uid) \ |
33 | hash_long((unsigned long)uid, ecryptfs_hash_buckets) | 35 | hash_long((unsigned long)uid, ecryptfs_hash_buckets) |
34 | 36 | ||
35 | static unsigned int ecryptfs_msg_counter; | 37 | static u32 ecryptfs_msg_counter; |
36 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | 38 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; |
37 | 39 | ||
38 | /** | 40 | /** |
@@ -40,9 +42,10 @@ static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | |||
40 | * @msg_ctx: The context that was acquired from the free list | 42 | * @msg_ctx: The context that was acquired from the free list |
41 | * | 43 | * |
42 | * Acquires a context element from the free list and locks the mutex | 44 | * Acquires a context element from the free list and locks the mutex |
43 | * on the context. Returns zero on success; non-zero on error or upon | 45 | * on the context. Sets the msg_ctx task to current. Returns zero on |
44 | * failure to acquire a free context element. Be sure to lock the | 46 | * success; non-zero on error or upon failure to acquire a free |
45 | * list mutex before calling. | 47 | * context element. Must be called with ecryptfs_msg_ctx_lists_mux |
48 | * held. | ||
46 | */ | 49 | */ |
47 | static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx) | 50 | static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx) |
48 | { | 51 | { |
@@ -50,11 +53,11 @@ static int ecryptfs_acquire_free_msg_ctx(struct ecryptfs_msg_ctx **msg_ctx) | |||
50 | int rc; | 53 | int rc; |
51 | 54 | ||
52 | if (list_empty(&ecryptfs_msg_ctx_free_list)) { | 55 | if (list_empty(&ecryptfs_msg_ctx_free_list)) { |
53 | ecryptfs_printk(KERN_WARNING, "The eCryptfs free " | 56 | printk(KERN_WARNING "%s: The eCryptfs free " |
54 | "context list is empty. It may be helpful to " | 57 | "context list is empty. It may be helpful to " |
55 | "specify the ecryptfs_message_buf_len " | 58 | "specify the ecryptfs_message_buf_len " |
56 | "parameter to be greater than the current " | 59 | "parameter to be greater than the current " |
57 | "value of [%d]\n", ecryptfs_message_buf_len); | 60 | "value of [%d]\n", __func__, ecryptfs_message_buf_len); |
58 | rc = -ENOMEM; | 61 | rc = -ENOMEM; |
59 | goto out; | 62 | goto out; |
60 | } | 63 | } |
@@ -75,8 +78,7 @@ out: | |||
75 | * ecryptfs_msg_ctx_free_to_alloc | 78 | * ecryptfs_msg_ctx_free_to_alloc |
76 | * @msg_ctx: The context to move from the free list to the alloc list | 79 | * @msg_ctx: The context to move from the free list to the alloc list |
77 | * | 80 | * |
78 | * Be sure to lock the list mutex and the context mutex before | 81 | * Must be called with ecryptfs_msg_ctx_lists_mux held. |
79 | * calling. | ||
80 | */ | 82 | */ |
81 | static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx) | 83 | static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx) |
82 | { | 84 | { |
@@ -89,36 +91,39 @@ static void ecryptfs_msg_ctx_free_to_alloc(struct ecryptfs_msg_ctx *msg_ctx) | |||
89 | * ecryptfs_msg_ctx_alloc_to_free | 91 | * ecryptfs_msg_ctx_alloc_to_free |
90 | * @msg_ctx: The context to move from the alloc list to the free list | 92 | * @msg_ctx: The context to move from the alloc list to the free list |
91 | * | 93 | * |
92 | * Be sure to lock the list mutex and the context mutex before | 94 | * Must be called with ecryptfs_msg_ctx_lists_mux held. |
93 | * calling. | ||
94 | */ | 95 | */ |
95 | static void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) | 96 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) |
96 | { | 97 | { |
97 | list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list); | 98 | list_move(&(msg_ctx->node), &ecryptfs_msg_ctx_free_list); |
98 | if (msg_ctx->msg) | 99 | if (msg_ctx->msg) |
99 | kfree(msg_ctx->msg); | 100 | kfree(msg_ctx->msg); |
101 | msg_ctx->msg = NULL; | ||
100 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_FREE; | 102 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_FREE; |
101 | } | 103 | } |
102 | 104 | ||
103 | /** | 105 | /** |
104 | * ecryptfs_find_daemon_id | 106 | * ecryptfs_find_daemon_by_euid |
105 | * @uid: The user id which maps to the desired daemon id | 107 | * @euid: The effective user id which maps to the desired daemon id |
106 | * @id: If return value is zero, points to the desired daemon id | 108 | * @user_ns: The namespace in which @euid applies |
107 | * pointer | 109 | * @daemon: If return value is zero, points to the desired daemon pointer |
108 | * | 110 | * |
109 | * Search the hash list for the given user id. Returns zero if the | 111 | * Must be called with ecryptfs_daemon_hash_mux held. |
110 | * user id exists in the list; non-zero otherwise. The daemon id hash | 112 | * |
111 | * mutex should be held before calling this function. | 113 | * Search the hash list for the given user id. |
114 | * | ||
115 | * Returns zero if the user id exists in the list; non-zero otherwise. | ||
112 | */ | 116 | */ |
113 | static int ecryptfs_find_daemon_id(uid_t uid, struct ecryptfs_daemon_id **id) | 117 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, |
118 | struct user_namespace *user_ns) | ||
114 | { | 119 | { |
115 | struct hlist_node *elem; | 120 | struct hlist_node *elem; |
116 | int rc; | 121 | int rc; |
117 | 122 | ||
118 | hlist_for_each_entry(*id, elem, | 123 | hlist_for_each_entry(*daemon, elem, |
119 | &ecryptfs_daemon_id_hash[ecryptfs_uid_hash(uid)], | 124 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], |
120 | id_chain) { | 125 | euid_chain) { |
121 | if ((*id)->uid == uid) { | 126 | if ((*daemon)->euid == euid && (*daemon)->user_ns == user_ns) { |
122 | rc = 0; | 127 | rc = 0; |
123 | goto out; | 128 | goto out; |
124 | } | 129 | } |
@@ -128,181 +133,325 @@ out: | |||
128 | return rc; | 133 | return rc; |
129 | } | 134 | } |
130 | 135 | ||
131 | static int ecryptfs_send_raw_message(unsigned int transport, u16 msg_type, | 136 | static int |
132 | pid_t pid) | 137 | ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len, |
138 | u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx); | ||
139 | |||
140 | /** | ||
141 | * ecryptfs_send_raw_message | ||
142 | * @transport: Transport type | ||
143 | * @msg_type: Message type | ||
144 | * @daemon: Daemon struct for recipient of message | ||
145 | * | ||
146 | * A raw message is one that does not include an ecryptfs_message | ||
147 | * struct. It simply has a type. | ||
148 | * | ||
149 | * Must be called with ecryptfs_daemon_hash_mux held. | ||
150 | * | ||
151 | * Returns zero on success; non-zero otherwise | ||
152 | */ | ||
153 | static int ecryptfs_send_raw_message(unsigned int transport, u8 msg_type, | ||
154 | struct ecryptfs_daemon *daemon) | ||
133 | { | 155 | { |
156 | struct ecryptfs_msg_ctx *msg_ctx; | ||
134 | int rc; | 157 | int rc; |
135 | 158 | ||
136 | switch(transport) { | 159 | switch(transport) { |
137 | case ECRYPTFS_TRANSPORT_NETLINK: | 160 | case ECRYPTFS_TRANSPORT_NETLINK: |
138 | rc = ecryptfs_send_netlink(NULL, 0, NULL, msg_type, 0, pid); | 161 | rc = ecryptfs_send_netlink(NULL, 0, NULL, msg_type, 0, |
162 | daemon->pid); | ||
163 | break; | ||
164 | case ECRYPTFS_TRANSPORT_MISCDEV: | ||
165 | rc = ecryptfs_send_message_locked(transport, NULL, 0, msg_type, | ||
166 | &msg_ctx); | ||
167 | if (rc) { | ||
168 | printk(KERN_ERR "%s: Error whilst attempting to send " | ||
169 | "message via procfs; rc = [%d]\n", __func__, rc); | ||
170 | goto out; | ||
171 | } | ||
172 | /* Raw messages are logically context-free (e.g., no | ||
173 | * reply is expected), so we set the state of the | ||
174 | * ecryptfs_msg_ctx object to indicate that it should | ||
175 | * be freed as soon as the transport sends out the message. */ | ||
176 | mutex_lock(&msg_ctx->mux); | ||
177 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_NO_REPLY; | ||
178 | mutex_unlock(&msg_ctx->mux); | ||
139 | break; | 179 | break; |
140 | case ECRYPTFS_TRANSPORT_CONNECTOR: | 180 | case ECRYPTFS_TRANSPORT_CONNECTOR: |
141 | case ECRYPTFS_TRANSPORT_RELAYFS: | 181 | case ECRYPTFS_TRANSPORT_RELAYFS: |
142 | default: | 182 | default: |
143 | rc = -ENOSYS; | 183 | rc = -ENOSYS; |
144 | } | 184 | } |
185 | out: | ||
186 | return rc; | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct | ||
191 | * @daemon: Pointer to set to newly allocated daemon struct | ||
192 | * @euid: Effective user id for the daemon | ||
193 | * @user_ns: The namespace in which @euid applies | ||
194 | * @pid: Process id for the daemon | ||
195 | * | ||
196 | * Must be called ceremoniously while in possession of | ||
197 | * ecryptfs_sacred_daemon_hash_mux | ||
198 | * | ||
199 | * Returns zero on success; non-zero otherwise | ||
200 | */ | ||
201 | int | ||
202 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | ||
203 | struct user_namespace *user_ns, struct pid *pid) | ||
204 | { | ||
205 | int rc = 0; | ||
206 | |||
207 | (*daemon) = kzalloc(sizeof(**daemon), GFP_KERNEL); | ||
208 | if (!(*daemon)) { | ||
209 | rc = -ENOMEM; | ||
210 | printk(KERN_ERR "%s: Failed to allocate [%Zd] bytes of " | ||
211 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); | ||
212 | goto out; | ||
213 | } | ||
214 | (*daemon)->euid = euid; | ||
215 | (*daemon)->user_ns = get_user_ns(user_ns); | ||
216 | (*daemon)->pid = get_pid(pid); | ||
217 | (*daemon)->task = current; | ||
218 | mutex_init(&(*daemon)->mux); | ||
219 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); | ||
220 | init_waitqueue_head(&(*daemon)->wait); | ||
221 | (*daemon)->num_queued_msg_ctx = 0; | ||
222 | hlist_add_head(&(*daemon)->euid_chain, | ||
223 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)]); | ||
224 | out: | ||
145 | return rc; | 225 | return rc; |
146 | } | 226 | } |
147 | 227 | ||
148 | /** | 228 | /** |
149 | * ecryptfs_process_helo | 229 | * ecryptfs_process_helo |
150 | * @transport: The underlying transport (netlink, etc.) | 230 | * @transport: The underlying transport (netlink, etc.) |
151 | * @uid: The user ID owner of the message | 231 | * @euid: The user ID owner of the message |
232 | * @user_ns: The namespace in which @euid applies | ||
152 | * @pid: The process ID for the userspace program that sent the | 233 | * @pid: The process ID for the userspace program that sent the |
153 | * message | 234 | * message |
154 | * | 235 | * |
155 | * Adds the uid and pid values to the daemon id hash. If a uid | 236 | * Adds the euid and pid values to the daemon euid hash. If an euid |
156 | * already has a daemon pid registered, the daemon will be | 237 | * already has a daemon pid registered, the daemon will be |
157 | * unregistered before the new daemon id is put into the hash list. | 238 | * unregistered before the new daemon is put into the hash list. |
158 | * Returns zero after adding a new daemon id to the hash list; | 239 | * Returns zero after adding a new daemon to the hash list; |
159 | * non-zero otherwise. | 240 | * non-zero otherwise. |
160 | */ | 241 | */ |
161 | int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid) | 242 | int ecryptfs_process_helo(unsigned int transport, uid_t euid, |
243 | struct user_namespace *user_ns, struct pid *pid) | ||
162 | { | 244 | { |
163 | struct ecryptfs_daemon_id *new_id; | 245 | struct ecryptfs_daemon *new_daemon; |
164 | struct ecryptfs_daemon_id *old_id; | 246 | struct ecryptfs_daemon *old_daemon; |
165 | int rc; | 247 | int rc; |
166 | 248 | ||
167 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 249 | mutex_lock(&ecryptfs_daemon_hash_mux); |
168 | new_id = kmalloc(sizeof(*new_id), GFP_KERNEL); | 250 | rc = ecryptfs_find_daemon_by_euid(&old_daemon, euid, user_ns); |
169 | if (!new_id) { | 251 | if (rc != 0) { |
170 | rc = -ENOMEM; | ||
171 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory; unable " | ||
172 | "to register daemon [%d] for user [%d]\n", | ||
173 | pid, uid); | ||
174 | goto unlock; | ||
175 | } | ||
176 | if (!ecryptfs_find_daemon_id(uid, &old_id)) { | ||
177 | printk(KERN_WARNING "Received request from user [%d] " | 252 | printk(KERN_WARNING "Received request from user [%d] " |
178 | "to register daemon [%d]; unregistering daemon " | 253 | "to register daemon [0x%p]; unregistering daemon " |
179 | "[%d]\n", uid, pid, old_id->pid); | 254 | "[0x%p]\n", euid, pid, old_daemon->pid); |
180 | hlist_del(&old_id->id_chain); | 255 | rc = ecryptfs_send_raw_message(transport, ECRYPTFS_MSG_QUIT, |
181 | rc = ecryptfs_send_raw_message(transport, ECRYPTFS_NLMSG_QUIT, | 256 | old_daemon); |
182 | old_id->pid); | ||
183 | if (rc) | 257 | if (rc) |
184 | printk(KERN_WARNING "Failed to send QUIT " | 258 | printk(KERN_WARNING "Failed to send QUIT " |
185 | "message to daemon [%d]; rc = [%d]\n", | 259 | "message to daemon [0x%p]; rc = [%d]\n", |
186 | old_id->pid, rc); | 260 | old_daemon->pid, rc); |
187 | kfree(old_id); | 261 | hlist_del(&old_daemon->euid_chain); |
262 | kfree(old_daemon); | ||
188 | } | 263 | } |
189 | new_id->uid = uid; | 264 | rc = ecryptfs_spawn_daemon(&new_daemon, euid, user_ns, pid); |
190 | new_id->pid = pid; | 265 | if (rc) |
191 | hlist_add_head(&new_id->id_chain, | 266 | printk(KERN_ERR "%s: The gods are displeased with this attempt " |
192 | &ecryptfs_daemon_id_hash[ecryptfs_uid_hash(uid)]); | 267 | "to create a new daemon object for euid [%d]; pid " |
193 | rc = 0; | 268 | "[0x%p]; rc = [%d]\n", __func__, euid, pid, rc); |
194 | unlock: | 269 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
195 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 270 | return rc; |
271 | } | ||
272 | |||
273 | /** | ||
274 | * ecryptfs_exorcise_daemon - Destroy the daemon struct | ||
275 | * | ||
276 | * Must be called ceremoniously while in possession of | ||
277 | * ecryptfs_daemon_hash_mux and the daemon's own mux. | ||
278 | */ | ||
279 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | ||
280 | { | ||
281 | struct ecryptfs_msg_ctx *msg_ctx, *msg_ctx_tmp; | ||
282 | int rc = 0; | ||
283 | |||
284 | mutex_lock(&daemon->mux); | ||
285 | if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) | ||
286 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { | ||
287 | rc = -EBUSY; | ||
288 | printk(KERN_WARNING "%s: Attempt to destroy daemon with pid " | ||
289 | "[0x%p], but it is in the midst of a read or a poll\n", | ||
290 | __func__, daemon->pid); | ||
291 | mutex_unlock(&daemon->mux); | ||
292 | goto out; | ||
293 | } | ||
294 | list_for_each_entry_safe(msg_ctx, msg_ctx_tmp, | ||
295 | &daemon->msg_ctx_out_queue, daemon_out_list) { | ||
296 | list_del(&msg_ctx->daemon_out_list); | ||
297 | daemon->num_queued_msg_ctx--; | ||
298 | printk(KERN_WARNING "%s: Warning: dropping message that is in " | ||
299 | "the out queue of a dying daemon\n", __func__); | ||
300 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); | ||
301 | } | ||
302 | hlist_del(&daemon->euid_chain); | ||
303 | if (daemon->task) | ||
304 | wake_up_process(daemon->task); | ||
305 | if (daemon->pid) | ||
306 | put_pid(daemon->pid); | ||
307 | if (daemon->user_ns) | ||
308 | put_user_ns(daemon->user_ns); | ||
309 | mutex_unlock(&daemon->mux); | ||
310 | memset(daemon, 0, sizeof(*daemon)); | ||
311 | kfree(daemon); | ||
312 | out: | ||
196 | return rc; | 313 | return rc; |
197 | } | 314 | } |
198 | 315 | ||
199 | /** | 316 | /** |
200 | * ecryptfs_process_quit | 317 | * ecryptfs_process_quit |
201 | * @uid: The user ID owner of the message | 318 | * @euid: The user ID owner of the message |
319 | * @user_ns: The namespace in which @euid applies | ||
202 | * @pid: The process ID for the userspace program that sent the | 320 | * @pid: The process ID for the userspace program that sent the |
203 | * message | 321 | * message |
204 | * | 322 | * |
205 | * Deletes the corresponding daemon id for the given uid and pid, if | 323 | * Deletes the corresponding daemon for the given euid and pid, if |
206 | * it is the registered that is requesting the deletion. Returns zero | 324 | * it is the registered that is requesting the deletion. Returns zero |
207 | * after deleting the desired daemon id; non-zero otherwise. | 325 | * after deleting the desired daemon; non-zero otherwise. |
208 | */ | 326 | */ |
209 | int ecryptfs_process_quit(uid_t uid, pid_t pid) | 327 | int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, |
328 | struct pid *pid) | ||
210 | { | 329 | { |
211 | struct ecryptfs_daemon_id *id; | 330 | struct ecryptfs_daemon *daemon; |
212 | int rc; | 331 | int rc; |
213 | 332 | ||
214 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 333 | mutex_lock(&ecryptfs_daemon_hash_mux); |
215 | if (ecryptfs_find_daemon_id(uid, &id)) { | 334 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, user_ns); |
335 | if (rc || !daemon) { | ||
216 | rc = -EINVAL; | 336 | rc = -EINVAL; |
217 | ecryptfs_printk(KERN_ERR, "Received request from user [%d] to " | 337 | printk(KERN_ERR "Received request from user [%d] to " |
218 | "unregister unrecognized daemon [%d]\n", uid, | 338 | "unregister unrecognized daemon [0x%p]\n", euid, pid); |
219 | pid); | 339 | goto out_unlock; |
220 | goto unlock; | ||
221 | } | 340 | } |
222 | if (id->pid != pid) { | 341 | rc = ecryptfs_exorcise_daemon(daemon); |
223 | rc = -EINVAL; | 342 | out_unlock: |
224 | ecryptfs_printk(KERN_WARNING, "Received request from user [%d] " | 343 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
225 | "with pid [%d] to unregister daemon [%d]\n", | ||
226 | uid, pid, id->pid); | ||
227 | goto unlock; | ||
228 | } | ||
229 | hlist_del(&id->id_chain); | ||
230 | kfree(id); | ||
231 | rc = 0; | ||
232 | unlock: | ||
233 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
234 | return rc; | 344 | return rc; |
235 | } | 345 | } |
236 | 346 | ||
237 | /** | 347 | /** |
238 | * ecryptfs_process_reponse | 348 | * ecryptfs_process_reponse |
239 | * @msg: The ecryptfs message received; the caller should sanity check | 349 | * @msg: The ecryptfs message received; the caller should sanity check |
240 | * msg->data_len | 350 | * msg->data_len and free the memory |
241 | * @pid: The process ID of the userspace application that sent the | 351 | * @pid: The process ID of the userspace application that sent the |
242 | * message | 352 | * message |
243 | * @seq: The sequence number of the message | 353 | * @seq: The sequence number of the message; must match the sequence |
354 | * number for the existing message context waiting for this | ||
355 | * response | ||
356 | * | ||
357 | * Processes a response message after sending an operation request to | ||
358 | * userspace. Some other process is awaiting this response. Before | ||
359 | * sending out its first communications, the other process allocated a | ||
360 | * msg_ctx from the ecryptfs_msg_ctx_arr at a particular index. The | ||
361 | * response message contains this index so that we can copy over the | ||
362 | * response message into the msg_ctx that the process holds a | ||
363 | * reference to. The other process is going to wake up, check to see | ||
364 | * that msg_ctx->state == ECRYPTFS_MSG_CTX_STATE_DONE, and then | ||
365 | * proceed to read off and process the response message. Returns zero | ||
366 | * upon delivery to desired context element; non-zero upon delivery | ||
367 | * failure or error. | ||
244 | * | 368 | * |
245 | * Processes a response message after sending a operation request to | 369 | * Returns zero on success; non-zero otherwise |
246 | * userspace. Returns zero upon delivery to desired context element; | ||
247 | * non-zero upon delivery failure or error. | ||
248 | */ | 370 | */ |
249 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, | 371 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, |
250 | pid_t pid, u32 seq) | 372 | struct user_namespace *user_ns, struct pid *pid, |
373 | u32 seq) | ||
251 | { | 374 | { |
252 | struct ecryptfs_daemon_id *id; | 375 | struct ecryptfs_daemon *daemon; |
253 | struct ecryptfs_msg_ctx *msg_ctx; | 376 | struct ecryptfs_msg_ctx *msg_ctx; |
254 | int msg_size; | 377 | size_t msg_size; |
378 | struct nsproxy *nsproxy; | ||
379 | struct user_namespace *current_user_ns; | ||
255 | int rc; | 380 | int rc; |
256 | 381 | ||
257 | if (msg->index >= ecryptfs_message_buf_len) { | 382 | if (msg->index >= ecryptfs_message_buf_len) { |
258 | rc = -EINVAL; | 383 | rc = -EINVAL; |
259 | ecryptfs_printk(KERN_ERR, "Attempt to reference " | 384 | printk(KERN_ERR "%s: Attempt to reference " |
260 | "context buffer at index [%d]; maximum " | 385 | "context buffer at index [%d]; maximum " |
261 | "allowable is [%d]\n", msg->index, | 386 | "allowable is [%d]\n", __func__, msg->index, |
262 | (ecryptfs_message_buf_len - 1)); | 387 | (ecryptfs_message_buf_len - 1)); |
263 | goto out; | 388 | goto out; |
264 | } | 389 | } |
265 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; | 390 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; |
266 | mutex_lock(&msg_ctx->mux); | 391 | mutex_lock(&msg_ctx->mux); |
267 | if (ecryptfs_find_daemon_id(msg_ctx->task->euid, &id)) { | 392 | mutex_lock(&ecryptfs_daemon_hash_mux); |
393 | rcu_read_lock(); | ||
394 | nsproxy = task_nsproxy(msg_ctx->task); | ||
395 | if (nsproxy == NULL) { | ||
268 | rc = -EBADMSG; | 396 | rc = -EBADMSG; |
269 | ecryptfs_printk(KERN_WARNING, "User [%d] received a " | 397 | printk(KERN_ERR "%s: Receiving process is a zombie. Dropping " |
270 | "message response from process [%d] but does " | 398 | "message.\n", __func__); |
271 | "not have a registered daemon\n", | 399 | rcu_read_unlock(); |
272 | msg_ctx->task->euid, pid); | 400 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
273 | goto wake_up; | 401 | goto wake_up; |
274 | } | 402 | } |
275 | if (msg_ctx->task->euid != uid) { | 403 | current_user_ns = nsproxy->user_ns; |
404 | rc = ecryptfs_find_daemon_by_euid(&daemon, msg_ctx->task->euid, | ||
405 | current_user_ns); | ||
406 | rcu_read_unlock(); | ||
407 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
408 | if (rc) { | ||
409 | rc = -EBADMSG; | ||
410 | printk(KERN_WARNING "%s: User [%d] received a " | ||
411 | "message response from process [0x%p] but does " | ||
412 | "not have a registered daemon\n", __func__, | ||
413 | msg_ctx->task->euid, pid); | ||
414 | goto wake_up; | ||
415 | } | ||
416 | if (msg_ctx->task->euid != euid) { | ||
276 | rc = -EBADMSG; | 417 | rc = -EBADMSG; |
277 | ecryptfs_printk(KERN_WARNING, "Received message from user " | 418 | printk(KERN_WARNING "%s: Received message from user " |
278 | "[%d]; expected message from user [%d]\n", | 419 | "[%d]; expected message from user [%d]\n", __func__, |
279 | uid, msg_ctx->task->euid); | 420 | euid, msg_ctx->task->euid); |
280 | goto unlock; | 421 | goto unlock; |
281 | } | 422 | } |
282 | if (id->pid != pid) { | 423 | if (current_user_ns != user_ns) { |
283 | rc = -EBADMSG; | 424 | rc = -EBADMSG; |
284 | ecryptfs_printk(KERN_ERR, "User [%d] received a " | 425 | printk(KERN_WARNING "%s: Received message from user_ns " |
285 | "message response from an unrecognized " | 426 | "[0x%p]; expected message from user_ns [0x%p]\n", |
286 | "process [%d]\n", msg_ctx->task->euid, pid); | 427 | __func__, user_ns, nsproxy->user_ns); |
428 | goto unlock; | ||
429 | } | ||
430 | if (daemon->pid != pid) { | ||
431 | rc = -EBADMSG; | ||
432 | printk(KERN_ERR "%s: User [%d] sent a message response " | ||
433 | "from an unrecognized process [0x%p]\n", | ||
434 | __func__, msg_ctx->task->euid, pid); | ||
287 | goto unlock; | 435 | goto unlock; |
288 | } | 436 | } |
289 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { | 437 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { |
290 | rc = -EINVAL; | 438 | rc = -EINVAL; |
291 | ecryptfs_printk(KERN_WARNING, "Desired context element is not " | 439 | printk(KERN_WARNING "%s: Desired context element is not " |
292 | "pending a response\n"); | 440 | "pending a response\n", __func__); |
293 | goto unlock; | 441 | goto unlock; |
294 | } else if (msg_ctx->counter != seq) { | 442 | } else if (msg_ctx->counter != seq) { |
295 | rc = -EINVAL; | 443 | rc = -EINVAL; |
296 | ecryptfs_printk(KERN_WARNING, "Invalid message sequence; " | 444 | printk(KERN_WARNING "%s: Invalid message sequence; " |
297 | "expected [%d]; received [%d]\n", | 445 | "expected [%d]; received [%d]\n", __func__, |
298 | msg_ctx->counter, seq); | 446 | msg_ctx->counter, seq); |
299 | goto unlock; | 447 | goto unlock; |
300 | } | 448 | } |
301 | msg_size = sizeof(*msg) + msg->data_len; | 449 | msg_size = (sizeof(*msg) + msg->data_len); |
302 | msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); | 450 | msg_ctx->msg = kmalloc(msg_size, GFP_KERNEL); |
303 | if (!msg_ctx->msg) { | 451 | if (!msg_ctx->msg) { |
304 | rc = -ENOMEM; | 452 | rc = -ENOMEM; |
305 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | 453 | printk(KERN_ERR "%s: Failed to allocate [%Zd] bytes of " |
454 | "GFP_KERNEL memory\n", __func__, msg_size); | ||
306 | goto unlock; | 455 | goto unlock; |
307 | } | 456 | } |
308 | memcpy(msg_ctx->msg, msg, msg_size); | 457 | memcpy(msg_ctx->msg, msg, msg_size); |
@@ -317,34 +466,38 @@ out: | |||
317 | } | 466 | } |
318 | 467 | ||
319 | /** | 468 | /** |
320 | * ecryptfs_send_message | 469 | * ecryptfs_send_message_locked |
321 | * @transport: The transport over which to send the message (i.e., | 470 | * @transport: The transport over which to send the message (i.e., |
322 | * netlink) | 471 | * netlink) |
323 | * @data: The data to send | 472 | * @data: The data to send |
324 | * @data_len: The length of data | 473 | * @data_len: The length of data |
325 | * @msg_ctx: The message context allocated for the send | 474 | * @msg_ctx: The message context allocated for the send |
475 | * | ||
476 | * Must be called with ecryptfs_daemon_hash_mux held. | ||
477 | * | ||
478 | * Returns zero on success; non-zero otherwise | ||
326 | */ | 479 | */ |
327 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | 480 | static int |
328 | struct ecryptfs_msg_ctx **msg_ctx) | 481 | ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len, |
482 | u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx) | ||
329 | { | 483 | { |
330 | struct ecryptfs_daemon_id *id; | 484 | struct ecryptfs_daemon *daemon; |
331 | int rc; | 485 | int rc; |
332 | 486 | ||
333 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 487 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, |
334 | if (ecryptfs_find_daemon_id(current->euid, &id)) { | 488 | current->nsproxy->user_ns); |
335 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 489 | if (rc || !daemon) { |
336 | rc = -ENOTCONN; | 490 | rc = -ENOTCONN; |
337 | ecryptfs_printk(KERN_ERR, "User [%d] does not have a daemon " | 491 | printk(KERN_ERR "%s: User [%d] does not have a daemon " |
338 | "registered\n", current->euid); | 492 | "registered\n", __func__, current->euid); |
339 | goto out; | 493 | goto out; |
340 | } | 494 | } |
341 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | ||
342 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | 495 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); |
343 | rc = ecryptfs_acquire_free_msg_ctx(msg_ctx); | 496 | rc = ecryptfs_acquire_free_msg_ctx(msg_ctx); |
344 | if (rc) { | 497 | if (rc) { |
345 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | 498 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); |
346 | ecryptfs_printk(KERN_WARNING, "Could not claim a free " | 499 | printk(KERN_WARNING "%s: Could not claim a free " |
347 | "context element\n"); | 500 | "context element\n", __func__); |
348 | goto out; | 501 | goto out; |
349 | } | 502 | } |
350 | ecryptfs_msg_ctx_free_to_alloc(*msg_ctx); | 503 | ecryptfs_msg_ctx_free_to_alloc(*msg_ctx); |
@@ -352,23 +505,50 @@ int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | |||
352 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | 505 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); |
353 | switch (transport) { | 506 | switch (transport) { |
354 | case ECRYPTFS_TRANSPORT_NETLINK: | 507 | case ECRYPTFS_TRANSPORT_NETLINK: |
355 | rc = ecryptfs_send_netlink(data, data_len, *msg_ctx, | 508 | rc = ecryptfs_send_netlink(data, data_len, *msg_ctx, msg_type, |
356 | ECRYPTFS_NLMSG_REQUEST, 0, id->pid); | 509 | 0, daemon->pid); |
510 | break; | ||
511 | case ECRYPTFS_TRANSPORT_MISCDEV: | ||
512 | rc = ecryptfs_send_miscdev(data, data_len, *msg_ctx, msg_type, | ||
513 | 0, daemon); | ||
357 | break; | 514 | break; |
358 | case ECRYPTFS_TRANSPORT_CONNECTOR: | 515 | case ECRYPTFS_TRANSPORT_CONNECTOR: |
359 | case ECRYPTFS_TRANSPORT_RELAYFS: | 516 | case ECRYPTFS_TRANSPORT_RELAYFS: |
360 | default: | 517 | default: |
361 | rc = -ENOSYS; | 518 | rc = -ENOSYS; |
362 | } | 519 | } |
363 | if (rc) { | 520 | if (rc) |
364 | printk(KERN_ERR "Error attempting to send message to userspace " | 521 | printk(KERN_ERR "%s: Error attempting to send message to " |
365 | "daemon; rc = [%d]\n", rc); | 522 | "userspace daemon; rc = [%d]\n", __func__, rc); |
366 | } | ||
367 | out: | 523 | out: |
368 | return rc; | 524 | return rc; |
369 | } | 525 | } |
370 | 526 | ||
371 | /** | 527 | /** |
528 | * ecryptfs_send_message | ||
529 | * @transport: The transport over which to send the message (i.e., | ||
530 | * netlink) | ||
531 | * @data: The data to send | ||
532 | * @data_len: The length of data | ||
533 | * @msg_ctx: The message context allocated for the send | ||
534 | * | ||
535 | * Grabs ecryptfs_daemon_hash_mux. | ||
536 | * | ||
537 | * Returns zero on success; non-zero otherwise | ||
538 | */ | ||
539 | int ecryptfs_send_message(unsigned int transport, char *data, int data_len, | ||
540 | struct ecryptfs_msg_ctx **msg_ctx) | ||
541 | { | ||
542 | int rc; | ||
543 | |||
544 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
545 | rc = ecryptfs_send_message_locked(transport, data, data_len, | ||
546 | ECRYPTFS_MSG_REQUEST, msg_ctx); | ||
547 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
548 | return rc; | ||
549 | } | ||
550 | |||
551 | /** | ||
372 | * ecryptfs_wait_for_response | 552 | * ecryptfs_wait_for_response |
373 | * @msg_ctx: The context that was assigned when sending a message | 553 | * @msg_ctx: The context that was assigned when sending a message |
374 | * @msg: The incoming message from userspace; not set if rc != 0 | 554 | * @msg: The incoming message from userspace; not set if rc != 0 |
@@ -377,7 +557,7 @@ out: | |||
377 | * of time exceeds ecryptfs_message_wait_timeout. If zero is | 557 | * of time exceeds ecryptfs_message_wait_timeout. If zero is |
378 | * returned, msg will point to a valid message from userspace; a | 558 | * returned, msg will point to a valid message from userspace; a |
379 | * non-zero value is returned upon failure to receive a message or an | 559 | * non-zero value is returned upon failure to receive a message or an |
380 | * error occurs. | 560 | * error occurs. Callee must free @msg on success. |
381 | */ | 561 | */ |
382 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | 562 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, |
383 | struct ecryptfs_message **msg) | 563 | struct ecryptfs_message **msg) |
@@ -413,32 +593,32 @@ int ecryptfs_init_messaging(unsigned int transport) | |||
413 | 593 | ||
414 | if (ecryptfs_number_of_users > ECRYPTFS_MAX_NUM_USERS) { | 594 | if (ecryptfs_number_of_users > ECRYPTFS_MAX_NUM_USERS) { |
415 | ecryptfs_number_of_users = ECRYPTFS_MAX_NUM_USERS; | 595 | ecryptfs_number_of_users = ECRYPTFS_MAX_NUM_USERS; |
416 | ecryptfs_printk(KERN_WARNING, "Specified number of users is " | 596 | printk(KERN_WARNING "%s: Specified number of users is " |
417 | "too large, defaulting to [%d] users\n", | 597 | "too large, defaulting to [%d] users\n", __func__, |
418 | ecryptfs_number_of_users); | 598 | ecryptfs_number_of_users); |
419 | } | 599 | } |
420 | mutex_init(&ecryptfs_daemon_id_hash_mux); | 600 | mutex_init(&ecryptfs_daemon_hash_mux); |
421 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 601 | mutex_lock(&ecryptfs_daemon_hash_mux); |
422 | ecryptfs_hash_buckets = 1; | 602 | ecryptfs_hash_buckets = 1; |
423 | while (ecryptfs_number_of_users >> ecryptfs_hash_buckets) | 603 | while (ecryptfs_number_of_users >> ecryptfs_hash_buckets) |
424 | ecryptfs_hash_buckets++; | 604 | ecryptfs_hash_buckets++; |
425 | ecryptfs_daemon_id_hash = kmalloc(sizeof(struct hlist_head) | 605 | ecryptfs_daemon_hash = kmalloc((sizeof(struct hlist_head) |
426 | * ecryptfs_hash_buckets, GFP_KERNEL); | 606 | * ecryptfs_hash_buckets), GFP_KERNEL); |
427 | if (!ecryptfs_daemon_id_hash) { | 607 | if (!ecryptfs_daemon_hash) { |
428 | rc = -ENOMEM; | 608 | rc = -ENOMEM; |
429 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | 609 | printk(KERN_ERR "%s: Failed to allocate memory\n", __func__); |
430 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 610 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
431 | goto out; | 611 | goto out; |
432 | } | 612 | } |
433 | for (i = 0; i < ecryptfs_hash_buckets; i++) | 613 | for (i = 0; i < ecryptfs_hash_buckets; i++) |
434 | INIT_HLIST_HEAD(&ecryptfs_daemon_id_hash[i]); | 614 | INIT_HLIST_HEAD(&ecryptfs_daemon_hash[i]); |
435 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 615 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
436 | |||
437 | ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx) | 616 | ecryptfs_msg_ctx_arr = kmalloc((sizeof(struct ecryptfs_msg_ctx) |
438 | * ecryptfs_message_buf_len), GFP_KERNEL); | 617 | * ecryptfs_message_buf_len), |
618 | GFP_KERNEL); | ||
439 | if (!ecryptfs_msg_ctx_arr) { | 619 | if (!ecryptfs_msg_ctx_arr) { |
440 | rc = -ENOMEM; | 620 | rc = -ENOMEM; |
441 | ecryptfs_printk(KERN_ERR, "Failed to allocate memory\n"); | 621 | printk(KERN_ERR "%s: Failed to allocate memory\n", __func__); |
442 | goto out; | 622 | goto out; |
443 | } | 623 | } |
444 | mutex_init(&ecryptfs_msg_ctx_lists_mux); | 624 | mutex_init(&ecryptfs_msg_ctx_lists_mux); |
@@ -446,6 +626,7 @@ int ecryptfs_init_messaging(unsigned int transport) | |||
446 | ecryptfs_msg_counter = 0; | 626 | ecryptfs_msg_counter = 0; |
447 | for (i = 0; i < ecryptfs_message_buf_len; i++) { | 627 | for (i = 0; i < ecryptfs_message_buf_len; i++) { |
448 | INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].node); | 628 | INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].node); |
629 | INIT_LIST_HEAD(&ecryptfs_msg_ctx_arr[i].daemon_out_list); | ||
449 | mutex_init(&ecryptfs_msg_ctx_arr[i].mux); | 630 | mutex_init(&ecryptfs_msg_ctx_arr[i].mux); |
450 | mutex_lock(&ecryptfs_msg_ctx_arr[i].mux); | 631 | mutex_lock(&ecryptfs_msg_ctx_arr[i].mux); |
451 | ecryptfs_msg_ctx_arr[i].index = i; | 632 | ecryptfs_msg_ctx_arr[i].index = i; |
@@ -464,6 +645,11 @@ int ecryptfs_init_messaging(unsigned int transport) | |||
464 | if (rc) | 645 | if (rc) |
465 | ecryptfs_release_messaging(transport); | 646 | ecryptfs_release_messaging(transport); |
466 | break; | 647 | break; |
648 | case ECRYPTFS_TRANSPORT_MISCDEV: | ||
649 | rc = ecryptfs_init_ecryptfs_miscdev(); | ||
650 | if (rc) | ||
651 | ecryptfs_release_messaging(transport); | ||
652 | break; | ||
467 | case ECRYPTFS_TRANSPORT_CONNECTOR: | 653 | case ECRYPTFS_TRANSPORT_CONNECTOR: |
468 | case ECRYPTFS_TRANSPORT_RELAYFS: | 654 | case ECRYPTFS_TRANSPORT_RELAYFS: |
469 | default: | 655 | default: |
@@ -488,27 +674,37 @@ void ecryptfs_release_messaging(unsigned int transport) | |||
488 | kfree(ecryptfs_msg_ctx_arr); | 674 | kfree(ecryptfs_msg_ctx_arr); |
489 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); | 675 | mutex_unlock(&ecryptfs_msg_ctx_lists_mux); |
490 | } | 676 | } |
491 | if (ecryptfs_daemon_id_hash) { | 677 | if (ecryptfs_daemon_hash) { |
492 | struct hlist_node *elem; | 678 | struct hlist_node *elem; |
493 | struct ecryptfs_daemon_id *id; | 679 | struct ecryptfs_daemon *daemon; |
494 | int i; | 680 | int i; |
495 | 681 | ||
496 | mutex_lock(&ecryptfs_daemon_id_hash_mux); | 682 | mutex_lock(&ecryptfs_daemon_hash_mux); |
497 | for (i = 0; i < ecryptfs_hash_buckets; i++) { | 683 | for (i = 0; i < ecryptfs_hash_buckets; i++) { |
498 | hlist_for_each_entry(id, elem, | 684 | int rc; |
499 | &ecryptfs_daemon_id_hash[i], | 685 | |
500 | id_chain) { | 686 | hlist_for_each_entry(daemon, elem, |
501 | hlist_del(elem); | 687 | &ecryptfs_daemon_hash[i], |
502 | kfree(id); | 688 | euid_chain) { |
689 | rc = ecryptfs_exorcise_daemon(daemon); | ||
690 | if (rc) | ||
691 | printk(KERN_ERR "%s: Error whilst " | ||
692 | "attempting to destroy daemon; " | ||
693 | "rc = [%d]. Dazed and confused, " | ||
694 | "but trying to continue.\n", | ||
695 | __func__, rc); | ||
503 | } | 696 | } |
504 | } | 697 | } |
505 | kfree(ecryptfs_daemon_id_hash); | 698 | kfree(ecryptfs_daemon_hash); |
506 | mutex_unlock(&ecryptfs_daemon_id_hash_mux); | 699 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
507 | } | 700 | } |
508 | switch(transport) { | 701 | switch(transport) { |
509 | case ECRYPTFS_TRANSPORT_NETLINK: | 702 | case ECRYPTFS_TRANSPORT_NETLINK: |
510 | ecryptfs_release_netlink(); | 703 | ecryptfs_release_netlink(); |
511 | break; | 704 | break; |
705 | case ECRYPTFS_TRANSPORT_MISCDEV: | ||
706 | ecryptfs_destroy_ecryptfs_miscdev(); | ||
707 | break; | ||
512 | case ECRYPTFS_TRANSPORT_CONNECTOR: | 708 | case ECRYPTFS_TRANSPORT_CONNECTOR: |
513 | case ECRYPTFS_TRANSPORT_RELAYFS: | 709 | case ECRYPTFS_TRANSPORT_RELAYFS: |
514 | default: | 710 | default: |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c new file mode 100644 index 000000000000..788995efd1d3 --- /dev/null +++ b/fs/ecryptfs/miscdev.c | |||
@@ -0,0 +1,598 @@ | |||
1 | /** | ||
2 | * eCryptfs: Linux filesystem encryption layer | ||
3 | * | ||
4 | * Copyright (C) 2008 International Business Machines Corp. | ||
5 | * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License version | ||
9 | * 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
19 | * 02111-1307, USA. | ||
20 | */ | ||
21 | |||
22 | #include <linux/fs.h> | ||
23 | #include <linux/hash.h> | ||
24 | #include <linux/random.h> | ||
25 | #include <linux/miscdevice.h> | ||
26 | #include <linux/poll.h> | ||
27 | #include <linux/wait.h> | ||
28 | #include <linux/module.h> | ||
29 | #include "ecryptfs_kernel.h" | ||
30 | |||
31 | static atomic_t ecryptfs_num_miscdev_opens; | ||
32 | |||
33 | /** | ||
34 | * ecryptfs_miscdev_poll | ||
35 | * @file: dev file (ignored) | ||
36 | * @pt: dev poll table (ignored) | ||
37 | * | ||
38 | * Returns the poll mask | ||
39 | */ | ||
40 | static unsigned int | ||
41 | ecryptfs_miscdev_poll(struct file *file, poll_table *pt) | ||
42 | { | ||
43 | struct ecryptfs_daemon *daemon; | ||
44 | unsigned int mask = 0; | ||
45 | int rc; | ||
46 | |||
47 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
48 | /* TODO: Just use file->private_data? */ | ||
49 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | ||
50 | current->nsproxy->user_ns); | ||
51 | BUG_ON(rc || !daemon); | ||
52 | mutex_lock(&daemon->mux); | ||
53 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
54 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | ||
55 | printk(KERN_WARNING "%s: Attempt to poll on zombified " | ||
56 | "daemon\n", __func__); | ||
57 | goto out_unlock_daemon; | ||
58 | } | ||
59 | if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) | ||
60 | goto out_unlock_daemon; | ||
61 | if (daemon->flags & ECRYPTFS_DAEMON_IN_POLL) | ||
62 | goto out_unlock_daemon; | ||
63 | daemon->flags |= ECRYPTFS_DAEMON_IN_POLL; | ||
64 | mutex_unlock(&daemon->mux); | ||
65 | poll_wait(file, &daemon->wait, pt); | ||
66 | mutex_lock(&daemon->mux); | ||
67 | if (!list_empty(&daemon->msg_ctx_out_queue)) | ||
68 | mask |= POLLIN | POLLRDNORM; | ||
69 | out_unlock_daemon: | ||
70 | daemon->flags &= ~ECRYPTFS_DAEMON_IN_POLL; | ||
71 | mutex_unlock(&daemon->mux); | ||
72 | return mask; | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * ecryptfs_miscdev_open | ||
77 | * @inode: inode of miscdev handle (ignored) | ||
78 | * @file: file for miscdev handle (ignored) | ||
79 | * | ||
80 | * Returns zero on success; non-zero otherwise | ||
81 | */ | ||
82 | static int | ||
83 | ecryptfs_miscdev_open(struct inode *inode, struct file *file) | ||
84 | { | ||
85 | struct ecryptfs_daemon *daemon = NULL; | ||
86 | int rc; | ||
87 | |||
88 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
89 | rc = try_module_get(THIS_MODULE); | ||
90 | if (rc == 0) { | ||
91 | rc = -EIO; | ||
92 | printk(KERN_ERR "%s: Error attempting to increment module use " | ||
93 | "count; rc = [%d]\n", __func__, rc); | ||
94 | goto out_unlock_daemon_list; | ||
95 | } | ||
96 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | ||
97 | current->nsproxy->user_ns); | ||
98 | if (rc || !daemon) { | ||
99 | rc = ecryptfs_spawn_daemon(&daemon, current->euid, | ||
100 | current->nsproxy->user_ns, | ||
101 | task_pid(current)); | ||
102 | if (rc) { | ||
103 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " | ||
104 | "rc = [%d]\n", __func__, rc); | ||
105 | goto out_module_put_unlock_daemon_list; | ||
106 | } | ||
107 | } | ||
108 | mutex_lock(&daemon->mux); | ||
109 | if (daemon->pid != task_pid(current)) { | ||
110 | rc = -EINVAL; | ||
111 | printk(KERN_ERR "%s: pid [0x%p] has registered with euid [%d], " | ||
112 | "but pid [0x%p] has attempted to open the handle " | ||
113 | "instead\n", __func__, daemon->pid, daemon->euid, | ||
114 | task_pid(current)); | ||
115 | goto out_unlock_daemon; | ||
116 | } | ||
117 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { | ||
118 | rc = -EBUSY; | ||
119 | printk(KERN_ERR "%s: Miscellaneous device handle may only be " | ||
120 | "opened once per daemon; pid [0x%p] already has this " | ||
121 | "handle open\n", __func__, daemon->pid); | ||
122 | goto out_unlock_daemon; | ||
123 | } | ||
124 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; | ||
125 | atomic_inc(&ecryptfs_num_miscdev_opens); | ||
126 | out_unlock_daemon: | ||
127 | mutex_unlock(&daemon->mux); | ||
128 | out_module_put_unlock_daemon_list: | ||
129 | if (rc) | ||
130 | module_put(THIS_MODULE); | ||
131 | out_unlock_daemon_list: | ||
132 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
133 | return rc; | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * ecryptfs_miscdev_release | ||
138 | * @inode: inode of fs/ecryptfs/euid handle (ignored) | ||
139 | * @file: file for fs/ecryptfs/euid handle (ignored) | ||
140 | * | ||
141 | * This keeps the daemon registered until the daemon sends another | ||
142 | * ioctl to fs/ecryptfs/ctl or until the kernel module unregisters. | ||
143 | * | ||
144 | * Returns zero on success; non-zero otherwise | ||
145 | */ | ||
146 | static int | ||
147 | ecryptfs_miscdev_release(struct inode *inode, struct file *file) | ||
148 | { | ||
149 | struct ecryptfs_daemon *daemon = NULL; | ||
150 | int rc; | ||
151 | |||
152 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
153 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | ||
154 | current->nsproxy->user_ns); | ||
155 | BUG_ON(rc || !daemon); | ||
156 | mutex_lock(&daemon->mux); | ||
157 | BUG_ON(daemon->pid != task_pid(current)); | ||
158 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); | ||
159 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; | ||
160 | atomic_dec(&ecryptfs_num_miscdev_opens); | ||
161 | mutex_unlock(&daemon->mux); | ||
162 | rc = ecryptfs_exorcise_daemon(daemon); | ||
163 | if (rc) { | ||
164 | printk(KERN_CRIT "%s: Fatal error whilst attempting to " | ||
165 | "shut down daemon; rc = [%d]. Please report this " | ||
166 | "bug.\n", __func__, rc); | ||
167 | BUG(); | ||
168 | } | ||
169 | module_put(THIS_MODULE); | ||
170 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
171 | return rc; | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * ecryptfs_send_miscdev | ||
176 | * @data: Data to send to daemon; may be NULL | ||
177 | * @data_size: Amount of data to send to daemon | ||
178 | * @msg_ctx: Message context, which is used to handle the reply. If | ||
179 | * this is NULL, then we do not expect a reply. | ||
180 | * @msg_type: Type of message | ||
181 | * @msg_flags: Flags for message | ||
182 | * @daemon: eCryptfs daemon object | ||
183 | * | ||
184 | * Add msg_ctx to queue and then, if it exists, notify the blocked | ||
185 | * miscdevess about the data being available. Must be called with | ||
186 | * ecryptfs_daemon_hash_mux held. | ||
187 | * | ||
188 | * Returns zero on success; non-zero otherwise | ||
189 | */ | ||
190 | int ecryptfs_send_miscdev(char *data, size_t data_size, | ||
191 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, | ||
192 | u16 msg_flags, struct ecryptfs_daemon *daemon) | ||
193 | { | ||
194 | int rc = 0; | ||
195 | |||
196 | mutex_lock(&msg_ctx->mux); | ||
197 | if (data) { | ||
198 | msg_ctx->msg = kmalloc((sizeof(*msg_ctx->msg) + data_size), | ||
199 | GFP_KERNEL); | ||
200 | if (!msg_ctx->msg) { | ||
201 | rc = -ENOMEM; | ||
202 | printk(KERN_ERR "%s: Out of memory whilst attempting " | ||
203 | "to kmalloc(%Zd, GFP_KERNEL)\n", __func__, | ||
204 | (sizeof(*msg_ctx->msg) + data_size)); | ||
205 | goto out_unlock; | ||
206 | } | ||
207 | } else | ||
208 | msg_ctx->msg = NULL; | ||
209 | msg_ctx->msg->index = msg_ctx->index; | ||
210 | msg_ctx->msg->data_len = data_size; | ||
211 | msg_ctx->type = msg_type; | ||
212 | if (data) { | ||
213 | memcpy(msg_ctx->msg->data, data, data_size); | ||
214 | msg_ctx->msg_size = (sizeof(*msg_ctx->msg) + data_size); | ||
215 | } else | ||
216 | msg_ctx->msg_size = 0; | ||
217 | mutex_lock(&daemon->mux); | ||
218 | list_add_tail(&msg_ctx->daemon_out_list, &daemon->msg_ctx_out_queue); | ||
219 | daemon->num_queued_msg_ctx++; | ||
220 | wake_up_interruptible(&daemon->wait); | ||
221 | mutex_unlock(&daemon->mux); | ||
222 | out_unlock: | ||
223 | mutex_unlock(&msg_ctx->mux); | ||
224 | return rc; | ||
225 | } | ||
226 | |||
227 | /** | ||
228 | * ecryptfs_miscdev_read - format and send message from queue | ||
229 | * @file: fs/ecryptfs/euid miscdevfs handle (ignored) | ||
230 | * @buf: User buffer into which to copy the next message on the daemon queue | ||
231 | * @count: Amount of space available in @buf | ||
232 | * @ppos: Offset in file (ignored) | ||
233 | * | ||
234 | * Pulls the most recent message from the daemon queue, formats it for | ||
235 | * being sent via a miscdevfs handle, and copies it into @buf | ||
236 | * | ||
237 | * Returns the number of bytes copied into the user buffer | ||
238 | */ | ||
239 | static ssize_t | ||
240 | ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, | ||
241 | loff_t *ppos) | ||
242 | { | ||
243 | struct ecryptfs_daemon *daemon; | ||
244 | struct ecryptfs_msg_ctx *msg_ctx; | ||
245 | size_t packet_length_size; | ||
246 | u32 counter_nbo; | ||
247 | char packet_length[3]; | ||
248 | size_t i; | ||
249 | size_t total_length; | ||
250 | int rc; | ||
251 | |||
252 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
253 | /* TODO: Just use file->private_data? */ | ||
254 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | ||
255 | current->nsproxy->user_ns); | ||
256 | BUG_ON(rc || !daemon); | ||
257 | mutex_lock(&daemon->mux); | ||
258 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | ||
259 | rc = 0; | ||
260 | printk(KERN_WARNING "%s: Attempt to read from zombified " | ||
261 | "daemon\n", __func__); | ||
262 | goto out_unlock_daemon; | ||
263 | } | ||
264 | if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) { | ||
265 | rc = 0; | ||
266 | goto out_unlock_daemon; | ||
267 | } | ||
268 | /* This daemon will not go away so long as this flag is set */ | ||
269 | daemon->flags |= ECRYPTFS_DAEMON_IN_READ; | ||
270 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
271 | check_list: | ||
272 | if (list_empty(&daemon->msg_ctx_out_queue)) { | ||
273 | mutex_unlock(&daemon->mux); | ||
274 | rc = wait_event_interruptible( | ||
275 | daemon->wait, !list_empty(&daemon->msg_ctx_out_queue)); | ||
276 | mutex_lock(&daemon->mux); | ||
277 | if (rc < 0) { | ||
278 | rc = 0; | ||
279 | goto out_unlock_daemon; | ||
280 | } | ||
281 | } | ||
282 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | ||
283 | rc = 0; | ||
284 | goto out_unlock_daemon; | ||
285 | } | ||
286 | if (list_empty(&daemon->msg_ctx_out_queue)) { | ||
287 | /* Something else jumped in since the | ||
288 | * wait_event_interruptable() and removed the | ||
289 | * message from the queue; try again */ | ||
290 | goto check_list; | ||
291 | } | ||
292 | BUG_ON(current->euid != daemon->euid); | ||
293 | BUG_ON(current->nsproxy->user_ns != daemon->user_ns); | ||
294 | BUG_ON(task_pid(current) != daemon->pid); | ||
295 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, | ||
296 | struct ecryptfs_msg_ctx, daemon_out_list); | ||
297 | BUG_ON(!msg_ctx); | ||
298 | mutex_lock(&msg_ctx->mux); | ||
299 | if (msg_ctx->msg) { | ||
300 | rc = ecryptfs_write_packet_length(packet_length, | ||
301 | msg_ctx->msg_size, | ||
302 | &packet_length_size); | ||
303 | if (rc) { | ||
304 | rc = 0; | ||
305 | printk(KERN_WARNING "%s: Error writing packet length; " | ||
306 | "rc = [%d]\n", __func__, rc); | ||
307 | goto out_unlock_msg_ctx; | ||
308 | } | ||
309 | } else { | ||
310 | packet_length_size = 0; | ||
311 | msg_ctx->msg_size = 0; | ||
312 | } | ||
313 | /* miscdevfs packet format: | ||
314 | * Octet 0: Type | ||
315 | * Octets 1-4: network byte order msg_ctx->counter | ||
316 | * Octets 5-N0: Size of struct ecryptfs_message to follow | ||
317 | * Octets N0-N1: struct ecryptfs_message (including data) | ||
318 | * | ||
319 | * Octets 5-N1 not written if the packet type does not | ||
320 | * include a message */ | ||
321 | total_length = (1 + 4 + packet_length_size + msg_ctx->msg_size); | ||
322 | if (count < total_length) { | ||
323 | rc = 0; | ||
324 | printk(KERN_WARNING "%s: Only given user buffer of " | ||
325 | "size [%Zd], but we need [%Zd] to read the " | ||
326 | "pending message\n", __func__, count, total_length); | ||
327 | goto out_unlock_msg_ctx; | ||
328 | } | ||
329 | i = 0; | ||
330 | buf[i++] = msg_ctx->type; | ||
331 | counter_nbo = cpu_to_be32(msg_ctx->counter); | ||
332 | memcpy(&buf[i], (char *)&counter_nbo, 4); | ||
333 | i += 4; | ||
334 | if (msg_ctx->msg) { | ||
335 | memcpy(&buf[i], packet_length, packet_length_size); | ||
336 | i += packet_length_size; | ||
337 | rc = copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size); | ||
338 | if (rc) { | ||
339 | printk(KERN_ERR "%s: copy_to_user returned error " | ||
340 | "[%d]\n", __func__, rc); | ||
341 | goto out_unlock_msg_ctx; | ||
342 | } | ||
343 | i += msg_ctx->msg_size; | ||
344 | } | ||
345 | rc = i; | ||
346 | list_del(&msg_ctx->daemon_out_list); | ||
347 | kfree(msg_ctx->msg); | ||
348 | msg_ctx->msg = NULL; | ||
349 | /* We do not expect a reply from the userspace daemon for any | ||
350 | * message type other than ECRYPTFS_MSG_REQUEST */ | ||
351 | if (msg_ctx->type != ECRYPTFS_MSG_REQUEST) | ||
352 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); | ||
353 | out_unlock_msg_ctx: | ||
354 | mutex_unlock(&msg_ctx->mux); | ||
355 | out_unlock_daemon: | ||
356 | daemon->flags &= ~ECRYPTFS_DAEMON_IN_READ; | ||
357 | mutex_unlock(&daemon->mux); | ||
358 | return rc; | ||
359 | } | ||
360 | |||
361 | /** | ||
362 | * ecryptfs_miscdev_helo | ||
363 | * @euid: effective user id of miscdevess sending helo packet | ||
364 | * @user_ns: The namespace in which @euid applies | ||
365 | * @pid: miscdevess id of miscdevess sending helo packet | ||
366 | * | ||
367 | * Returns zero on success; non-zero otherwise | ||
368 | */ | ||
369 | static int ecryptfs_miscdev_helo(uid_t euid, struct user_namespace *user_ns, | ||
370 | struct pid *pid) | ||
371 | { | ||
372 | int rc; | ||
373 | |||
374 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_MISCDEV, euid, user_ns, | ||
375 | pid); | ||
376 | if (rc) | ||
377 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); | ||
378 | return rc; | ||
379 | } | ||
380 | |||
381 | /** | ||
382 | * ecryptfs_miscdev_quit | ||
383 | * @euid: effective user id of miscdevess sending quit packet | ||
384 | * @user_ns: The namespace in which @euid applies | ||
385 | * @pid: miscdevess id of miscdevess sending quit packet | ||
386 | * | ||
387 | * Returns zero on success; non-zero otherwise | ||
388 | */ | ||
389 | static int ecryptfs_miscdev_quit(uid_t euid, struct user_namespace *user_ns, | ||
390 | struct pid *pid) | ||
391 | { | ||
392 | int rc; | ||
393 | |||
394 | rc = ecryptfs_process_quit(euid, user_ns, pid); | ||
395 | if (rc) | ||
396 | printk(KERN_WARNING | ||
397 | "Error processing QUIT message; rc = [%d]\n", rc); | ||
398 | return rc; | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon | ||
403 | * @data: Bytes comprising struct ecryptfs_message | ||
404 | * @data_size: sizeof(struct ecryptfs_message) + data len | ||
405 | * @euid: Effective user id of miscdevess sending the miscdev response | ||
406 | * @user_ns: The namespace in which @euid applies | ||
407 | * @pid: Miscdevess id of miscdevess sending the miscdev response | ||
408 | * @seq: Sequence number for miscdev response packet | ||
409 | * | ||
410 | * Returns zero on success; non-zero otherwise | ||
411 | */ | ||
412 | static int ecryptfs_miscdev_response(char *data, size_t data_size, | ||
413 | uid_t euid, struct user_namespace *user_ns, | ||
414 | struct pid *pid, u32 seq) | ||
415 | { | ||
416 | struct ecryptfs_message *msg = (struct ecryptfs_message *)data; | ||
417 | int rc; | ||
418 | |||
419 | if ((sizeof(*msg) + msg->data_len) != data_size) { | ||
420 | printk(KERN_WARNING "%s: (sizeof(*msg) + msg->data_len) = " | ||
421 | "[%Zd]; data_size = [%Zd]. Invalid packet.\n", __func__, | ||
422 | (sizeof(*msg) + msg->data_len), data_size); | ||
423 | rc = -EINVAL; | ||
424 | goto out; | ||
425 | } | ||
426 | rc = ecryptfs_process_response(msg, euid, user_ns, pid, seq); | ||
427 | if (rc) | ||
428 | printk(KERN_ERR | ||
429 | "Error processing response message; rc = [%d]\n", rc); | ||
430 | out: | ||
431 | return rc; | ||
432 | } | ||
433 | |||
434 | /** | ||
435 | * ecryptfs_miscdev_write - handle write to daemon miscdev handle | ||
436 | * @file: File for misc dev handle (ignored) | ||
437 | * @buf: Buffer containing user data | ||
438 | * @count: Amount of data in @buf | ||
439 | * @ppos: Pointer to offset in file (ignored) | ||
440 | * | ||
441 | * miscdevfs packet format: | ||
442 | * Octet 0: Type | ||
443 | * Octets 1-4: network byte order msg_ctx->counter (0's for non-response) | ||
444 | * Octets 5-N0: Size of struct ecryptfs_message to follow | ||
445 | * Octets N0-N1: struct ecryptfs_message (including data) | ||
446 | * | ||
447 | * Returns the number of bytes read from @buf | ||
448 | */ | ||
449 | static ssize_t | ||
450 | ecryptfs_miscdev_write(struct file *file, const char __user *buf, | ||
451 | size_t count, loff_t *ppos) | ||
452 | { | ||
453 | u32 counter_nbo, seq; | ||
454 | size_t packet_size, packet_size_length, i; | ||
455 | ssize_t sz = 0; | ||
456 | char *data; | ||
457 | int rc; | ||
458 | |||
459 | if (count == 0) | ||
460 | goto out; | ||
461 | data = kmalloc(count, GFP_KERNEL); | ||
462 | if (!data) { | ||
463 | printk(KERN_ERR "%s: Out of memory whilst attempting to " | ||
464 | "kmalloc([%Zd], GFP_KERNEL)\n", __func__, count); | ||
465 | goto out; | ||
466 | } | ||
467 | rc = copy_from_user(data, buf, count); | ||
468 | if (rc) { | ||
469 | printk(KERN_ERR "%s: copy_from_user returned error [%d]\n", | ||
470 | __func__, rc); | ||
471 | goto out_free; | ||
472 | } | ||
473 | sz = count; | ||
474 | i = 0; | ||
475 | switch (data[i++]) { | ||
476 | case ECRYPTFS_MSG_RESPONSE: | ||
477 | if (count < (1 + 4 + 1 + sizeof(struct ecryptfs_message))) { | ||
478 | printk(KERN_WARNING "%s: Minimum acceptable packet " | ||
479 | "size is [%Zd], but amount of data written is " | ||
480 | "only [%Zd]. Discarding response packet.\n", | ||
481 | __func__, | ||
482 | (1 + 4 + 1 + sizeof(struct ecryptfs_message)), | ||
483 | count); | ||
484 | goto out_free; | ||
485 | } | ||
486 | memcpy((char *)&counter_nbo, &data[i], 4); | ||
487 | seq = be32_to_cpu(counter_nbo); | ||
488 | i += 4; | ||
489 | rc = ecryptfs_parse_packet_length(&data[i], &packet_size, | ||
490 | &packet_size_length); | ||
491 | if (rc) { | ||
492 | printk(KERN_WARNING "%s: Error parsing packet length; " | ||
493 | "rc = [%d]\n", __func__, rc); | ||
494 | goto out_free; | ||
495 | } | ||
496 | i += packet_size_length; | ||
497 | if ((1 + 4 + packet_size_length + packet_size) != count) { | ||
498 | printk(KERN_WARNING "%s: (1 + packet_size_length([%Zd])" | ||
499 | " + packet_size([%Zd]))([%Zd]) != " | ||
500 | "count([%Zd]). Invalid packet format.\n", | ||
501 | __func__, packet_size_length, packet_size, | ||
502 | (1 + packet_size_length + packet_size), count); | ||
503 | goto out_free; | ||
504 | } | ||
505 | rc = ecryptfs_miscdev_response(&data[i], packet_size, | ||
506 | current->euid, | ||
507 | current->nsproxy->user_ns, | ||
508 | task_pid(current), seq); | ||
509 | if (rc) | ||
510 | printk(KERN_WARNING "%s: Failed to deliver miscdev " | ||
511 | "response to requesting operation; rc = [%d]\n", | ||
512 | __func__, rc); | ||
513 | break; | ||
514 | case ECRYPTFS_MSG_HELO: | ||
515 | rc = ecryptfs_miscdev_helo(current->euid, | ||
516 | current->nsproxy->user_ns, | ||
517 | task_pid(current)); | ||
518 | if (rc) { | ||
519 | printk(KERN_ERR "%s: Error attempting to process " | ||
520 | "helo from pid [0x%p]; rc = [%d]\n", __func__, | ||
521 | task_pid(current), rc); | ||
522 | goto out_free; | ||
523 | } | ||
524 | break; | ||
525 | case ECRYPTFS_MSG_QUIT: | ||
526 | rc = ecryptfs_miscdev_quit(current->euid, | ||
527 | current->nsproxy->user_ns, | ||
528 | task_pid(current)); | ||
529 | if (rc) { | ||
530 | printk(KERN_ERR "%s: Error attempting to process " | ||
531 | "quit from pid [0x%p]; rc = [%d]\n", __func__, | ||
532 | task_pid(current), rc); | ||
533 | goto out_free; | ||
534 | } | ||
535 | break; | ||
536 | default: | ||
537 | ecryptfs_printk(KERN_WARNING, "Dropping miscdev " | ||
538 | "message of unrecognized type [%d]\n", | ||
539 | data[0]); | ||
540 | break; | ||
541 | } | ||
542 | out_free: | ||
543 | kfree(data); | ||
544 | out: | ||
545 | return sz; | ||
546 | } | ||
547 | |||
548 | |||
549 | static const struct file_operations ecryptfs_miscdev_fops = { | ||
550 | .open = ecryptfs_miscdev_open, | ||
551 | .poll = ecryptfs_miscdev_poll, | ||
552 | .read = ecryptfs_miscdev_read, | ||
553 | .write = ecryptfs_miscdev_write, | ||
554 | .release = ecryptfs_miscdev_release, | ||
555 | }; | ||
556 | |||
557 | static struct miscdevice ecryptfs_miscdev = { | ||
558 | .minor = MISC_DYNAMIC_MINOR, | ||
559 | .name = "ecryptfs", | ||
560 | .fops = &ecryptfs_miscdev_fops | ||
561 | }; | ||
562 | |||
563 | /** | ||
564 | * ecryptfs_init_ecryptfs_miscdev | ||
565 | * | ||
566 | * Messages sent to the userspace daemon from the kernel are placed on | ||
567 | * a queue associated with the daemon. The next read against the | ||
568 | * miscdev handle by that daemon will return the oldest message placed | ||
569 | * on the message queue for the daemon. | ||
570 | * | ||
571 | * Returns zero on success; non-zero otherwise | ||
572 | */ | ||
573 | int ecryptfs_init_ecryptfs_miscdev(void) | ||
574 | { | ||
575 | int rc; | ||
576 | |||
577 | atomic_set(&ecryptfs_num_miscdev_opens, 0); | ||
578 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
579 | rc = misc_register(&ecryptfs_miscdev); | ||
580 | if (rc) | ||
581 | printk(KERN_ERR "%s: Failed to register miscellaneous device " | ||
582 | "for communications with userspace daemons; rc = [%d]\n", | ||
583 | __func__, rc); | ||
584 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
585 | return rc; | ||
586 | } | ||
587 | |||
588 | /** | ||
589 | * ecryptfs_destroy_ecryptfs_miscdev | ||
590 | * | ||
591 | * All of the daemons must be exorcised prior to calling this | ||
592 | * function. | ||
593 | */ | ||
594 | void ecryptfs_destroy_ecryptfs_miscdev(void) | ||
595 | { | ||
596 | BUG_ON(atomic_read(&ecryptfs_num_miscdev_opens) != 0); | ||
597 | misc_deregister(&ecryptfs_miscdev); | ||
598 | } | ||
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 6df1debdccce..2b6fe1e6e8ba 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -153,7 +153,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
153 | flush_dcache_page(page); | 153 | flush_dcache_page(page); |
154 | if (rc) { | 154 | if (rc) { |
155 | printk(KERN_ERR "%s: Error reading xattr " | 155 | printk(KERN_ERR "%s: Error reading xattr " |
156 | "region; rc = [%d]\n", __FUNCTION__, rc); | 156 | "region; rc = [%d]\n", __func__, rc); |
157 | goto out; | 157 | goto out; |
158 | } | 158 | } |
159 | } else { | 159 | } else { |
@@ -169,7 +169,7 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
169 | if (rc) { | 169 | if (rc) { |
170 | printk(KERN_ERR "%s: Error attempting to read " | 170 | printk(KERN_ERR "%s: Error attempting to read " |
171 | "extent at offset [%lld] in the lower " | 171 | "extent at offset [%lld] in the lower " |
172 | "file; rc = [%d]\n", __FUNCTION__, | 172 | "file; rc = [%d]\n", __func__, |
173 | lower_offset, rc); | 173 | lower_offset, rc); |
174 | goto out; | 174 | goto out; |
175 | } | 175 | } |
@@ -212,7 +212,7 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
212 | "the encrypted content from the lower " | 212 | "the encrypted content from the lower " |
213 | "file whilst inserting the metadata " | 213 | "file whilst inserting the metadata " |
214 | "from the xattr into the header; rc = " | 214 | "from the xattr into the header; rc = " |
215 | "[%d]\n", __FUNCTION__, rc); | 215 | "[%d]\n", __func__, rc); |
216 | goto out; | 216 | goto out; |
217 | } | 217 | } |
218 | 218 | ||
@@ -293,7 +293,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
293 | if (rc) { | 293 | if (rc) { |
294 | printk(KERN_ERR "%s: Error attemping to read " | 294 | printk(KERN_ERR "%s: Error attemping to read " |
295 | "lower page segment; rc = [%d]\n", | 295 | "lower page segment; rc = [%d]\n", |
296 | __FUNCTION__, rc); | 296 | __func__, rc); |
297 | ClearPageUptodate(page); | 297 | ClearPageUptodate(page); |
298 | goto out; | 298 | goto out; |
299 | } else | 299 | } else |
@@ -308,7 +308,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
308 | "from the lower file whilst " | 308 | "from the lower file whilst " |
309 | "inserting the metadata from " | 309 | "inserting the metadata from " |
310 | "the xattr into the header; rc " | 310 | "the xattr into the header; rc " |
311 | "= [%d]\n", __FUNCTION__, rc); | 311 | "= [%d]\n", __func__, rc); |
312 | ClearPageUptodate(page); | 312 | ClearPageUptodate(page); |
313 | goto out; | 313 | goto out; |
314 | } | 314 | } |
@@ -320,7 +320,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
320 | if (rc) { | 320 | if (rc) { |
321 | printk(KERN_ERR "%s: Error reading " | 321 | printk(KERN_ERR "%s: Error reading " |
322 | "page; rc = [%d]\n", | 322 | "page; rc = [%d]\n", |
323 | __FUNCTION__, rc); | 323 | __func__, rc); |
324 | ClearPageUptodate(page); | 324 | ClearPageUptodate(page); |
325 | goto out; | 325 | goto out; |
326 | } | 326 | } |
@@ -331,7 +331,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
331 | if (rc) { | 331 | if (rc) { |
332 | printk(KERN_ERR "%s: Error decrypting page " | 332 | printk(KERN_ERR "%s: Error decrypting page " |
333 | "at index [%ld]; rc = [%d]\n", | 333 | "at index [%ld]; rc = [%d]\n", |
334 | __FUNCTION__, page->index, rc); | 334 | __func__, page->index, rc); |
335 | ClearPageUptodate(page); | 335 | ClearPageUptodate(page); |
336 | goto out; | 336 | goto out; |
337 | } | 337 | } |
@@ -348,7 +348,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
348 | if (rc) { | 348 | if (rc) { |
349 | printk(KERN_ERR "%s: Error on attempt to " | 349 | printk(KERN_ERR "%s: Error on attempt to " |
350 | "truncate to (higher) offset [%lld];" | 350 | "truncate to (higher) offset [%lld];" |
351 | " rc = [%d]\n", __FUNCTION__, | 351 | " rc = [%d]\n", __func__, |
352 | prev_page_end_size, rc); | 352 | prev_page_end_size, rc); |
353 | goto out; | 353 | goto out; |
354 | } | 354 | } |
@@ -389,7 +389,7 @@ static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode) | |||
389 | kfree(file_size_virt); | 389 | kfree(file_size_virt); |
390 | if (rc) | 390 | if (rc) |
391 | printk(KERN_ERR "%s: Error writing file size to header; " | 391 | printk(KERN_ERR "%s: Error writing file size to header; " |
392 | "rc = [%d]\n", __FUNCTION__, rc); | 392 | "rc = [%d]\n", __func__, rc); |
393 | out: | 393 | out: |
394 | return rc; | 394 | return rc; |
395 | } | 395 | } |
diff --git a/fs/ecryptfs/netlink.c b/fs/ecryptfs/netlink.c index f638a698dc52..e0abad62b395 100644 --- a/fs/ecryptfs/netlink.c +++ b/fs/ecryptfs/netlink.c | |||
@@ -44,8 +44,8 @@ static struct sock *ecryptfs_nl_sock; | |||
44 | * upon sending the message; non-zero upon error. | 44 | * upon sending the message; non-zero upon error. |
45 | */ | 45 | */ |
46 | int ecryptfs_send_netlink(char *data, int data_len, | 46 | int ecryptfs_send_netlink(char *data, int data_len, |
47 | struct ecryptfs_msg_ctx *msg_ctx, u16 msg_type, | 47 | struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type, |
48 | u16 msg_flags, pid_t daemon_pid) | 48 | u16 msg_flags, struct pid *daemon_pid) |
49 | { | 49 | { |
50 | struct sk_buff *skb; | 50 | struct sk_buff *skb; |
51 | struct nlmsghdr *nlh; | 51 | struct nlmsghdr *nlh; |
@@ -60,7 +60,7 @@ int ecryptfs_send_netlink(char *data, int data_len, | |||
60 | ecryptfs_printk(KERN_ERR, "Failed to allocate socket buffer\n"); | 60 | ecryptfs_printk(KERN_ERR, "Failed to allocate socket buffer\n"); |
61 | goto out; | 61 | goto out; |
62 | } | 62 | } |
63 | nlh = NLMSG_PUT(skb, daemon_pid, msg_ctx ? msg_ctx->counter : 0, | 63 | nlh = NLMSG_PUT(skb, pid_nr(daemon_pid), msg_ctx ? msg_ctx->counter : 0, |
64 | msg_type, payload_len); | 64 | msg_type, payload_len); |
65 | nlh->nlmsg_flags = msg_flags; | 65 | nlh->nlmsg_flags = msg_flags; |
66 | if (msg_ctx && payload_len) { | 66 | if (msg_ctx && payload_len) { |
@@ -69,7 +69,7 @@ int ecryptfs_send_netlink(char *data, int data_len, | |||
69 | msg->data_len = data_len; | 69 | msg->data_len = data_len; |
70 | memcpy(msg->data, data, data_len); | 70 | memcpy(msg->data, data, data_len); |
71 | } | 71 | } |
72 | rc = netlink_unicast(ecryptfs_nl_sock, skb, daemon_pid, 0); | 72 | rc = netlink_unicast(ecryptfs_nl_sock, skb, pid_nr(daemon_pid), 0); |
73 | if (rc < 0) { | 73 | if (rc < 0) { |
74 | ecryptfs_printk(KERN_ERR, "Failed to send eCryptfs netlink " | 74 | ecryptfs_printk(KERN_ERR, "Failed to send eCryptfs netlink " |
75 | "message; rc = [%d]\n", rc); | 75 | "message; rc = [%d]\n", rc); |
@@ -99,6 +99,7 @@ static int ecryptfs_process_nl_response(struct sk_buff *skb) | |||
99 | { | 99 | { |
100 | struct nlmsghdr *nlh = nlmsg_hdr(skb); | 100 | struct nlmsghdr *nlh = nlmsg_hdr(skb); |
101 | struct ecryptfs_message *msg = NLMSG_DATA(nlh); | 101 | struct ecryptfs_message *msg = NLMSG_DATA(nlh); |
102 | struct pid *pid; | ||
102 | int rc; | 103 | int rc; |
103 | 104 | ||
104 | if (skb->len - NLMSG_HDRLEN - sizeof(*msg) != msg->data_len) { | 105 | if (skb->len - NLMSG_HDRLEN - sizeof(*msg) != msg->data_len) { |
@@ -107,8 +108,10 @@ static int ecryptfs_process_nl_response(struct sk_buff *skb) | |||
107 | "incorrectly specified data length\n"); | 108 | "incorrectly specified data length\n"); |
108 | goto out; | 109 | goto out; |
109 | } | 110 | } |
110 | rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid, | 111 | pid = find_get_pid(NETLINK_CREDS(skb)->pid); |
111 | NETLINK_CREDS(skb)->pid, nlh->nlmsg_seq); | 112 | rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid, NULL, |
113 | pid, nlh->nlmsg_seq); | ||
114 | put_pid(pid); | ||
112 | if (rc) | 115 | if (rc) |
113 | printk(KERN_ERR | 116 | printk(KERN_ERR |
114 | "Error processing response message; rc = [%d]\n", rc); | 117 | "Error processing response message; rc = [%d]\n", rc); |
@@ -126,11 +129,13 @@ out: | |||
126 | */ | 129 | */ |
127 | static int ecryptfs_process_nl_helo(struct sk_buff *skb) | 130 | static int ecryptfs_process_nl_helo(struct sk_buff *skb) |
128 | { | 131 | { |
132 | struct pid *pid; | ||
129 | int rc; | 133 | int rc; |
130 | 134 | ||
135 | pid = find_get_pid(NETLINK_CREDS(skb)->pid); | ||
131 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_NETLINK, | 136 | rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_NETLINK, |
132 | NETLINK_CREDS(skb)->uid, | 137 | NETLINK_CREDS(skb)->uid, NULL, pid); |
133 | NETLINK_CREDS(skb)->pid); | 138 | put_pid(pid); |
134 | if (rc) | 139 | if (rc) |
135 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); | 140 | printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc); |
136 | return rc; | 141 | return rc; |
@@ -147,10 +152,12 @@ static int ecryptfs_process_nl_helo(struct sk_buff *skb) | |||
147 | */ | 152 | */ |
148 | static int ecryptfs_process_nl_quit(struct sk_buff *skb) | 153 | static int ecryptfs_process_nl_quit(struct sk_buff *skb) |
149 | { | 154 | { |
155 | struct pid *pid; | ||
150 | int rc; | 156 | int rc; |
151 | 157 | ||
152 | rc = ecryptfs_process_quit(NETLINK_CREDS(skb)->uid, | 158 | pid = find_get_pid(NETLINK_CREDS(skb)->pid); |
153 | NETLINK_CREDS(skb)->pid); | 159 | rc = ecryptfs_process_quit(NETLINK_CREDS(skb)->uid, NULL, pid); |
160 | put_pid(pid); | ||
154 | if (rc) | 161 | if (rc) |
155 | printk(KERN_WARNING | 162 | printk(KERN_WARNING |
156 | "Error processing QUIT message; rc = [%d]\n", rc); | 163 | "Error processing QUIT message; rc = [%d]\n", rc); |
@@ -176,20 +183,20 @@ static void ecryptfs_receive_nl_message(struct sk_buff *skb) | |||
176 | goto free; | 183 | goto free; |
177 | } | 184 | } |
178 | switch (nlh->nlmsg_type) { | 185 | switch (nlh->nlmsg_type) { |
179 | case ECRYPTFS_NLMSG_RESPONSE: | 186 | case ECRYPTFS_MSG_RESPONSE: |
180 | if (ecryptfs_process_nl_response(skb)) { | 187 | if (ecryptfs_process_nl_response(skb)) { |
181 | ecryptfs_printk(KERN_WARNING, "Failed to " | 188 | ecryptfs_printk(KERN_WARNING, "Failed to " |
182 | "deliver netlink response to " | 189 | "deliver netlink response to " |
183 | "requesting operation\n"); | 190 | "requesting operation\n"); |
184 | } | 191 | } |
185 | break; | 192 | break; |
186 | case ECRYPTFS_NLMSG_HELO: | 193 | case ECRYPTFS_MSG_HELO: |
187 | if (ecryptfs_process_nl_helo(skb)) { | 194 | if (ecryptfs_process_nl_helo(skb)) { |
188 | ecryptfs_printk(KERN_WARNING, "Failed to " | 195 | ecryptfs_printk(KERN_WARNING, "Failed to " |
189 | "fulfill HELO request\n"); | 196 | "fulfill HELO request\n"); |
190 | } | 197 | } |
191 | break; | 198 | break; |
192 | case ECRYPTFS_NLMSG_QUIT: | 199 | case ECRYPTFS_MSG_QUIT: |
193 | if (ecryptfs_process_nl_quit(skb)) { | 200 | if (ecryptfs_process_nl_quit(skb)) { |
194 | ecryptfs_printk(KERN_WARNING, "Failed to " | 201 | ecryptfs_printk(KERN_WARNING, "Failed to " |
195 | "fulfill QUIT request\n"); | 202 | "fulfill QUIT request\n"); |
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 0c4928623bbc..ebf55150be56 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
@@ -55,7 +55,7 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, | |||
55 | set_fs(fs_save); | 55 | set_fs(fs_save); |
56 | if (octets_written < 0) { | 56 | if (octets_written < 0) { |
57 | printk(KERN_ERR "%s: octets_written = [%td]; " | 57 | printk(KERN_ERR "%s: octets_written = [%td]; " |
58 | "expected [%td]\n", __FUNCTION__, octets_written, size); | 58 | "expected [%td]\n", __func__, octets_written, size); |
59 | rc = -EINVAL; | 59 | rc = -EINVAL; |
60 | } | 60 | } |
61 | mutex_unlock(&inode_info->lower_file_mutex); | 61 | mutex_unlock(&inode_info->lower_file_mutex); |
@@ -153,7 +153,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
153 | rc = PTR_ERR(ecryptfs_page); | 153 | rc = PTR_ERR(ecryptfs_page); |
154 | printk(KERN_ERR "%s: Error getting page at " | 154 | printk(KERN_ERR "%s: Error getting page at " |
155 | "index [%ld] from eCryptfs inode " | 155 | "index [%ld] from eCryptfs inode " |
156 | "mapping; rc = [%d]\n", __FUNCTION__, | 156 | "mapping; rc = [%d]\n", __func__, |
157 | ecryptfs_page_idx, rc); | 157 | ecryptfs_page_idx, rc); |
158 | goto out; | 158 | goto out; |
159 | } | 159 | } |
@@ -165,7 +165,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
165 | if (rc) { | 165 | if (rc) { |
166 | printk(KERN_ERR "%s: Error decrypting " | 166 | printk(KERN_ERR "%s: Error decrypting " |
167 | "page; rc = [%d]\n", | 167 | "page; rc = [%d]\n", |
168 | __FUNCTION__, rc); | 168 | __func__, rc); |
169 | ClearPageUptodate(ecryptfs_page); | 169 | ClearPageUptodate(ecryptfs_page); |
170 | page_cache_release(ecryptfs_page); | 170 | page_cache_release(ecryptfs_page); |
171 | goto out; | 171 | goto out; |
@@ -202,7 +202,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
202 | page_cache_release(ecryptfs_page); | 202 | page_cache_release(ecryptfs_page); |
203 | if (rc) { | 203 | if (rc) { |
204 | printk(KERN_ERR "%s: Error encrypting " | 204 | printk(KERN_ERR "%s: Error encrypting " |
205 | "page; rc = [%d]\n", __FUNCTION__, rc); | 205 | "page; rc = [%d]\n", __func__, rc); |
206 | goto out; | 206 | goto out; |
207 | } | 207 | } |
208 | pos += num_bytes; | 208 | pos += num_bytes; |
@@ -254,7 +254,7 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | |||
254 | set_fs(fs_save); | 254 | set_fs(fs_save); |
255 | if (octets_read < 0) { | 255 | if (octets_read < 0) { |
256 | printk(KERN_ERR "%s: octets_read = [%td]; " | 256 | printk(KERN_ERR "%s: octets_read = [%td]; " |
257 | "expected [%td]\n", __FUNCTION__, octets_read, size); | 257 | "expected [%td]\n", __func__, octets_read, size); |
258 | rc = -EINVAL; | 258 | rc = -EINVAL; |
259 | } | 259 | } |
260 | mutex_unlock(&inode_info->lower_file_mutex); | 260 | mutex_unlock(&inode_info->lower_file_mutex); |
@@ -327,7 +327,7 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, | |||
327 | printk(KERN_ERR "%s: Attempt to read data past the end of the " | 327 | printk(KERN_ERR "%s: Attempt to read data past the end of the " |
328 | "file; offset = [%lld]; size = [%td]; " | 328 | "file; offset = [%lld]; size = [%td]; " |
329 | "ecryptfs_file_size = [%lld]\n", | 329 | "ecryptfs_file_size = [%lld]\n", |
330 | __FUNCTION__, offset, size, ecryptfs_file_size); | 330 | __func__, offset, size, ecryptfs_file_size); |
331 | goto out; | 331 | goto out; |
332 | } | 332 | } |
333 | pos = offset; | 333 | pos = offset; |
@@ -345,14 +345,14 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, | |||
345 | rc = PTR_ERR(ecryptfs_page); | 345 | rc = PTR_ERR(ecryptfs_page); |
346 | printk(KERN_ERR "%s: Error getting page at " | 346 | printk(KERN_ERR "%s: Error getting page at " |
347 | "index [%ld] from eCryptfs inode " | 347 | "index [%ld] from eCryptfs inode " |
348 | "mapping; rc = [%d]\n", __FUNCTION__, | 348 | "mapping; rc = [%d]\n", __func__, |
349 | ecryptfs_page_idx, rc); | 349 | ecryptfs_page_idx, rc); |
350 | goto out; | 350 | goto out; |
351 | } | 351 | } |
352 | rc = ecryptfs_decrypt_page(ecryptfs_page); | 352 | rc = ecryptfs_decrypt_page(ecryptfs_page); |
353 | if (rc) { | 353 | if (rc) { |
354 | printk(KERN_ERR "%s: Error decrypting " | 354 | printk(KERN_ERR "%s: Error decrypting " |
355 | "page; rc = [%d]\n", __FUNCTION__, rc); | 355 | "page; rc = [%d]\n", __func__, rc); |
356 | ClearPageUptodate(ecryptfs_page); | 356 | ClearPageUptodate(ecryptfs_page); |
357 | page_cache_release(ecryptfs_page); | 357 | page_cache_release(ecryptfs_page); |
358 | goto out; | 358 | goto out; |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index a415f42d32cf..0d237182d721 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -257,25 +257,6 @@ static inline int ep_cmp_ffd(struct epoll_filefd *p1, | |||
257 | (p1->file < p2->file ? -1 : p1->fd - p2->fd)); | 257 | (p1->file < p2->file ? -1 : p1->fd - p2->fd)); |
258 | } | 258 | } |
259 | 259 | ||
260 | /* Special initialization for the RB tree node to detect linkage */ | ||
261 | static inline void ep_rb_initnode(struct rb_node *n) | ||
262 | { | ||
263 | rb_set_parent(n, n); | ||
264 | } | ||
265 | |||
266 | /* Removes a node from the RB tree and marks it for a fast is-linked check */ | ||
267 | static inline void ep_rb_erase(struct rb_node *n, struct rb_root *r) | ||
268 | { | ||
269 | rb_erase(n, r); | ||
270 | rb_set_parent(n, n); | ||
271 | } | ||
272 | |||
273 | /* Fast check to verify that the item is linked to the main RB tree */ | ||
274 | static inline int ep_rb_linked(struct rb_node *n) | ||
275 | { | ||
276 | return rb_parent(n) != n; | ||
277 | } | ||
278 | |||
279 | /* Tells us if the item is currently linked */ | 260 | /* Tells us if the item is currently linked */ |
280 | static inline int ep_is_linked(struct list_head *p) | 261 | static inline int ep_is_linked(struct list_head *p) |
281 | { | 262 | { |
@@ -283,13 +264,13 @@ static inline int ep_is_linked(struct list_head *p) | |||
283 | } | 264 | } |
284 | 265 | ||
285 | /* Get the "struct epitem" from a wait queue pointer */ | 266 | /* Get the "struct epitem" from a wait queue pointer */ |
286 | static inline struct epitem * ep_item_from_wait(wait_queue_t *p) | 267 | static inline struct epitem *ep_item_from_wait(wait_queue_t *p) |
287 | { | 268 | { |
288 | return container_of(p, struct eppoll_entry, wait)->base; | 269 | return container_of(p, struct eppoll_entry, wait)->base; |
289 | } | 270 | } |
290 | 271 | ||
291 | /* Get the "struct epitem" from an epoll queue wrapper */ | 272 | /* Get the "struct epitem" from an epoll queue wrapper */ |
292 | static inline struct epitem * ep_item_from_epqueue(poll_table *p) | 273 | static inline struct epitem *ep_item_from_epqueue(poll_table *p) |
293 | { | 274 | { |
294 | return container_of(p, struct ep_pqueue, pt)->epi; | 275 | return container_of(p, struct ep_pqueue, pt)->epi; |
295 | } | 276 | } |
@@ -411,8 +392,7 @@ static int ep_remove(struct eventpoll *ep, struct epitem *epi) | |||
411 | list_del_init(&epi->fllink); | 392 | list_del_init(&epi->fllink); |
412 | spin_unlock(&file->f_ep_lock); | 393 | spin_unlock(&file->f_ep_lock); |
413 | 394 | ||
414 | if (ep_rb_linked(&epi->rbn)) | 395 | rb_erase(&epi->rbn, &ep->rbr); |
415 | ep_rb_erase(&epi->rbn, &ep->rbr); | ||
416 | 396 | ||
417 | spin_lock_irqsave(&ep->lock, flags); | 397 | spin_lock_irqsave(&ep->lock, flags); |
418 | if (ep_is_linked(&epi->rdllink)) | 398 | if (ep_is_linked(&epi->rdllink)) |
@@ -728,7 +708,6 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, | |||
728 | goto error_return; | 708 | goto error_return; |
729 | 709 | ||
730 | /* Item initialization follow here ... */ | 710 | /* Item initialization follow here ... */ |
731 | ep_rb_initnode(&epi->rbn); | ||
732 | INIT_LIST_HEAD(&epi->rdllink); | 711 | INIT_LIST_HEAD(&epi->rdllink); |
733 | INIT_LIST_HEAD(&epi->fllink); | 712 | INIT_LIST_HEAD(&epi->fllink); |
734 | INIT_LIST_HEAD(&epi->pwqlist); | 713 | INIT_LIST_HEAD(&epi->pwqlist); |
@@ -735,6 +735,7 @@ static int exec_mmap(struct mm_struct *mm) | |||
735 | tsk->active_mm = mm; | 735 | tsk->active_mm = mm; |
736 | activate_mm(active_mm, mm); | 736 | activate_mm(active_mm, mm); |
737 | task_unlock(tsk); | 737 | task_unlock(tsk); |
738 | mm_update_next_owner(mm); | ||
738 | arch_pick_mmap_layout(mm); | 739 | arch_pick_mmap_layout(mm); |
739 | if (old_mm) { | 740 | if (old_mm) { |
740 | up_read(&old_mm->mmap_sem); | 741 | up_read(&old_mm->mmap_sem); |
@@ -963,6 +964,8 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
963 | if (retval) | 964 | if (retval) |
964 | goto out; | 965 | goto out; |
965 | 966 | ||
967 | set_mm_exe_file(bprm->mm, bprm->file); | ||
968 | |||
966 | /* | 969 | /* |
967 | * Release all of the old mmap stuff | 970 | * Release all of the old mmap stuff |
968 | */ | 971 | */ |
@@ -1268,7 +1271,6 @@ int do_execve(char * filename, | |||
1268 | { | 1271 | { |
1269 | struct linux_binprm *bprm; | 1272 | struct linux_binprm *bprm; |
1270 | struct file *file; | 1273 | struct file *file; |
1271 | unsigned long env_p; | ||
1272 | struct files_struct *displaced; | 1274 | struct files_struct *displaced; |
1273 | int retval; | 1275 | int retval; |
1274 | 1276 | ||
@@ -1321,11 +1323,9 @@ int do_execve(char * filename, | |||
1321 | if (retval < 0) | 1323 | if (retval < 0) |
1322 | goto out; | 1324 | goto out; |
1323 | 1325 | ||
1324 | env_p = bprm->p; | ||
1325 | retval = copy_strings(bprm->argc, argv, bprm); | 1326 | retval = copy_strings(bprm->argc, argv, bprm); |
1326 | if (retval < 0) | 1327 | if (retval < 0) |
1327 | goto out; | 1328 | goto out; |
1328 | bprm->argv_len = env_p - bprm->p; | ||
1329 | 1329 | ||
1330 | retval = search_binary_handler(bprm,regs); | 1330 | retval = search_binary_handler(bprm,regs); |
1331 | if (retval >= 0) { | 1331 | if (retval >= 0) { |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index ef97f19c2f9d..9d57695de746 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -2449,17 +2449,10 @@ static void ext4_mb_history_init(struct super_block *sb) | |||
2449 | int i; | 2449 | int i; |
2450 | 2450 | ||
2451 | if (sbi->s_mb_proc != NULL) { | 2451 | if (sbi->s_mb_proc != NULL) { |
2452 | struct proc_dir_entry *p; | 2452 | proc_create_data("mb_history", S_IRUGO, sbi->s_mb_proc, |
2453 | p = create_proc_entry("mb_history", S_IRUGO, sbi->s_mb_proc); | 2453 | &ext4_mb_seq_history_fops, sb); |
2454 | if (p) { | 2454 | proc_create_data("mb_groups", S_IRUGO, sbi->s_mb_proc, |
2455 | p->proc_fops = &ext4_mb_seq_history_fops; | 2455 | &ext4_mb_seq_groups_fops, sb); |
2456 | p->data = sb; | ||
2457 | } | ||
2458 | p = create_proc_entry("mb_groups", S_IRUGO, sbi->s_mb_proc); | ||
2459 | if (p) { | ||
2460 | p->proc_fops = &ext4_mb_seq_groups_fops; | ||
2461 | p->data = sb; | ||
2462 | } | ||
2463 | } | 2456 | } |
2464 | 2457 | ||
2465 | sbi->s_mb_history_max = 1000; | 2458 | sbi->s_mb_history_max = 1000; |
@@ -2867,7 +2860,6 @@ static void ext4_mb_free_committed_blocks(struct super_block *sb) | |||
2867 | mb_debug("freed %u blocks in %u structures\n", count, count2); | 2860 | mb_debug("freed %u blocks in %u structures\n", count, count2); |
2868 | } | 2861 | } |
2869 | 2862 | ||
2870 | #define EXT4_ROOT "ext4" | ||
2871 | #define EXT4_MB_STATS_NAME "stats" | 2863 | #define EXT4_MB_STATS_NAME "stats" |
2872 | #define EXT4_MB_MAX_TO_SCAN_NAME "max_to_scan" | 2864 | #define EXT4_MB_MAX_TO_SCAN_NAME "max_to_scan" |
2873 | #define EXT4_MB_MIN_TO_SCAN_NAME "min_to_scan" | 2865 | #define EXT4_MB_MIN_TO_SCAN_NAME "min_to_scan" |
@@ -3007,9 +2999,9 @@ int __init init_ext4_mballoc(void) | |||
3007 | return -ENOMEM; | 2999 | return -ENOMEM; |
3008 | } | 3000 | } |
3009 | #ifdef CONFIG_PROC_FS | 3001 | #ifdef CONFIG_PROC_FS |
3010 | proc_root_ext4 = proc_mkdir(EXT4_ROOT, proc_root_fs); | 3002 | proc_root_ext4 = proc_mkdir("fs/ext4", NULL); |
3011 | if (proc_root_ext4 == NULL) | 3003 | if (proc_root_ext4 == NULL) |
3012 | printk(KERN_ERR "EXT4-fs: Unable to create %s\n", EXT4_ROOT); | 3004 | printk(KERN_ERR "EXT4-fs: Unable to create fs/ext4\n"); |
3013 | #endif | 3005 | #endif |
3014 | return 0; | 3006 | return 0; |
3015 | } | 3007 | } |
@@ -3020,7 +3012,7 @@ void exit_ext4_mballoc(void) | |||
3020 | kmem_cache_destroy(ext4_pspace_cachep); | 3012 | kmem_cache_destroy(ext4_pspace_cachep); |
3021 | kmem_cache_destroy(ext4_ac_cachep); | 3013 | kmem_cache_destroy(ext4_ac_cachep); |
3022 | #ifdef CONFIG_PROC_FS | 3014 | #ifdef CONFIG_PROC_FS |
3023 | remove_proc_entry(EXT4_ROOT, proc_root_fs); | 3015 | remove_proc_entry("fs/ext4", NULL); |
3024 | #endif | 3016 | #endif |
3025 | } | 3017 | } |
3026 | 3018 | ||
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 5f522a55b596..4e0a3dd9d677 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -1222,8 +1222,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1222 | brelse(bh); | 1222 | brelse(bh); |
1223 | goto out_invalid; | 1223 | goto out_invalid; |
1224 | } | 1224 | } |
1225 | logical_sector_size = | 1225 | logical_sector_size = get_unaligned_le16(&b->sector_size); |
1226 | le16_to_cpu(get_unaligned((__le16 *)&b->sector_size)); | ||
1227 | if (!is_power_of_2(logical_sector_size) | 1226 | if (!is_power_of_2(logical_sector_size) |
1228 | || (logical_sector_size < 512) | 1227 | || (logical_sector_size < 512) |
1229 | || (logical_sector_size > 4096)) { | 1228 | || (logical_sector_size > 4096)) { |
@@ -1322,8 +1321,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1322 | sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1; | 1321 | sbi->dir_per_block_bits = ffs(sbi->dir_per_block) - 1; |
1323 | 1322 | ||
1324 | sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length; | 1323 | sbi->dir_start = sbi->fat_start + sbi->fats * sbi->fat_length; |
1325 | sbi->dir_entries = | 1324 | sbi->dir_entries = get_unaligned_le16(&b->dir_entries); |
1326 | le16_to_cpu(get_unaligned((__le16 *)&b->dir_entries)); | ||
1327 | if (sbi->dir_entries & (sbi->dir_per_block - 1)) { | 1325 | if (sbi->dir_entries & (sbi->dir_per_block - 1)) { |
1328 | if (!silent) | 1326 | if (!silent) |
1329 | printk(KERN_ERR "FAT: bogus directroy-entries per block" | 1327 | printk(KERN_ERR "FAT: bogus directroy-entries per block" |
@@ -1335,7 +1333,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1335 | rootdir_sectors = sbi->dir_entries | 1333 | rootdir_sectors = sbi->dir_entries |
1336 | * sizeof(struct msdos_dir_entry) / sb->s_blocksize; | 1334 | * sizeof(struct msdos_dir_entry) / sb->s_blocksize; |
1337 | sbi->data_start = sbi->dir_start + rootdir_sectors; | 1335 | sbi->data_start = sbi->dir_start + rootdir_sectors; |
1338 | total_sectors = le16_to_cpu(get_unaligned((__le16 *)&b->sectors)); | 1336 | total_sectors = get_unaligned_le16(&b->sectors); |
1339 | if (total_sectors == 0) | 1337 | if (total_sectors == 0) |
1340 | total_sectors = le32_to_cpu(b->total_sect); | 1338 | total_sectors = le32_to_cpu(b->total_sect); |
1341 | 1339 | ||
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h index 2b46064f66b2..50ab5eecb99b 100644 --- a/fs/freevxfs/vxfs_extern.h +++ b/fs/freevxfs/vxfs_extern.h | |||
@@ -50,7 +50,11 @@ extern daddr_t vxfs_bmap1(struct inode *, long); | |||
50 | /* vxfs_fshead.c */ | 50 | /* vxfs_fshead.c */ |
51 | extern int vxfs_read_fshead(struct super_block *); | 51 | extern int vxfs_read_fshead(struct super_block *); |
52 | 52 | ||
53 | /* vxfs_immed.c */ | ||
54 | extern const struct inode_operations vxfs_immed_symlink_iops; | ||
55 | |||
53 | /* vxfs_inode.c */ | 56 | /* vxfs_inode.c */ |
57 | extern const struct address_space_operations vxfs_immed_aops; | ||
54 | extern struct kmem_cache *vxfs_inode_cachep; | 58 | extern struct kmem_cache *vxfs_inode_cachep; |
55 | extern void vxfs_dumpi(struct vxfs_inode_info *, ino_t); | 59 | extern void vxfs_dumpi(struct vxfs_inode_info *, ino_t); |
56 | extern struct inode * vxfs_get_fake_inode(struct super_block *, | 60 | extern struct inode * vxfs_get_fake_inode(struct super_block *, |
@@ -69,6 +73,7 @@ extern const struct file_operations vxfs_dir_operations; | |||
69 | extern int vxfs_read_olt(struct super_block *, u_long); | 73 | extern int vxfs_read_olt(struct super_block *, u_long); |
70 | 74 | ||
71 | /* vxfs_subr.c */ | 75 | /* vxfs_subr.c */ |
76 | extern const struct address_space_operations vxfs_aops; | ||
72 | extern struct page * vxfs_get_page(struct address_space *, u_long); | 77 | extern struct page * vxfs_get_page(struct address_space *, u_long); |
73 | extern void vxfs_put_page(struct page *); | 78 | extern void vxfs_put_page(struct page *); |
74 | extern struct buffer_head * vxfs_bread(struct inode *, int); | 79 | extern struct buffer_head * vxfs_bread(struct inode *, int); |
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c index 8a5959a61ba9..c36aeaf92e41 100644 --- a/fs/freevxfs/vxfs_immed.c +++ b/fs/freevxfs/vxfs_immed.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/namei.h> | 35 | #include <linux/namei.h> |
36 | 36 | ||
37 | #include "vxfs.h" | 37 | #include "vxfs.h" |
38 | #include "vxfs_extern.h" | ||
38 | #include "vxfs_inode.h" | 39 | #include "vxfs_inode.h" |
39 | 40 | ||
40 | 41 | ||
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c index ad88d2364bc2..9f3f2ceb73f0 100644 --- a/fs/freevxfs/vxfs_inode.c +++ b/fs/freevxfs/vxfs_inode.c | |||
@@ -41,11 +41,6 @@ | |||
41 | #include "vxfs_extern.h" | 41 | #include "vxfs_extern.h" |
42 | 42 | ||
43 | 43 | ||
44 | extern const struct address_space_operations vxfs_aops; | ||
45 | extern const struct address_space_operations vxfs_immed_aops; | ||
46 | |||
47 | extern const struct inode_operations vxfs_immed_symlink_iops; | ||
48 | |||
49 | struct kmem_cache *vxfs_inode_cachep; | 44 | struct kmem_cache *vxfs_inode_cachep; |
50 | 45 | ||
51 | 46 | ||
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 06557679ca41..ae45f77765c0 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -25,6 +25,45 @@ | |||
25 | #include <linux/buffer_head.h> | 25 | #include <linux/buffer_head.h> |
26 | #include "internal.h" | 26 | #include "internal.h" |
27 | 27 | ||
28 | |||
29 | /** | ||
30 | * writeback_acquire - attempt to get exclusive writeback access to a device | ||
31 | * @bdi: the device's backing_dev_info structure | ||
32 | * | ||
33 | * It is a waste of resources to have more than one pdflush thread blocked on | ||
34 | * a single request queue. Exclusion at the request_queue level is obtained | ||
35 | * via a flag in the request_queue's backing_dev_info.state. | ||
36 | * | ||
37 | * Non-request_queue-backed address_spaces will share default_backing_dev_info, | ||
38 | * unless they implement their own. Which is somewhat inefficient, as this | ||
39 | * may prevent concurrent writeback against multiple devices. | ||
40 | */ | ||
41 | static int writeback_acquire(struct backing_dev_info *bdi) | ||
42 | { | ||
43 | return !test_and_set_bit(BDI_pdflush, &bdi->state); | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * writeback_in_progress - determine whether there is writeback in progress | ||
48 | * @bdi: the device's backing_dev_info structure. | ||
49 | * | ||
50 | * Determine whether there is writeback in progress against a backing device. | ||
51 | */ | ||
52 | int writeback_in_progress(struct backing_dev_info *bdi) | ||
53 | { | ||
54 | return test_bit(BDI_pdflush, &bdi->state); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * writeback_release - relinquish exclusive writeback access against a device. | ||
59 | * @bdi: the device's backing_dev_info structure | ||
60 | */ | ||
61 | static void writeback_release(struct backing_dev_info *bdi) | ||
62 | { | ||
63 | BUG_ON(!writeback_in_progress(bdi)); | ||
64 | clear_bit(BDI_pdflush, &bdi->state); | ||
65 | } | ||
66 | |||
28 | /** | 67 | /** |
29 | * __mark_inode_dirty - internal function | 68 | * __mark_inode_dirty - internal function |
30 | * @inode: inode to mark | 69 | * @inode: inode to mark |
@@ -747,43 +786,4 @@ int generic_osync_inode(struct inode *inode, struct address_space *mapping, int | |||
747 | 786 | ||
748 | return err; | 787 | return err; |
749 | } | 788 | } |
750 | |||
751 | EXPORT_SYMBOL(generic_osync_inode); | 789 | EXPORT_SYMBOL(generic_osync_inode); |
752 | |||
753 | /** | ||
754 | * writeback_acquire - attempt to get exclusive writeback access to a device | ||
755 | * @bdi: the device's backing_dev_info structure | ||
756 | * | ||
757 | * It is a waste of resources to have more than one pdflush thread blocked on | ||
758 | * a single request queue. Exclusion at the request_queue level is obtained | ||
759 | * via a flag in the request_queue's backing_dev_info.state. | ||
760 | * | ||
761 | * Non-request_queue-backed address_spaces will share default_backing_dev_info, | ||
762 | * unless they implement their own. Which is somewhat inefficient, as this | ||
763 | * may prevent concurrent writeback against multiple devices. | ||
764 | */ | ||
765 | int writeback_acquire(struct backing_dev_info *bdi) | ||
766 | { | ||
767 | return !test_and_set_bit(BDI_pdflush, &bdi->state); | ||
768 | } | ||
769 | |||
770 | /** | ||
771 | * writeback_in_progress - determine whether there is writeback in progress | ||
772 | * @bdi: the device's backing_dev_info structure. | ||
773 | * | ||
774 | * Determine whether there is writeback in progress against a backing device. | ||
775 | */ | ||
776 | int writeback_in_progress(struct backing_dev_info *bdi) | ||
777 | { | ||
778 | return test_bit(BDI_pdflush, &bdi->state); | ||
779 | } | ||
780 | |||
781 | /** | ||
782 | * writeback_release - relinquish exclusive writeback access against a device. | ||
783 | * @bdi: the device's backing_dev_info structure | ||
784 | */ | ||
785 | void writeback_release(struct backing_dev_info *bdi) | ||
786 | { | ||
787 | BUG_ON(!writeback_in_progress(bdi)); | ||
788 | clear_bit(BDI_pdflush, &bdi->state); | ||
789 | } | ||
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 32de44ed0021..8cf67974adf6 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -297,7 +297,8 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
299 | p = match_strdup(&args[0]); | 299 | p = match_strdup(&args[0]); |
300 | hsb->nls_disk = load_nls(p); | 300 | if (p) |
301 | hsb->nls_disk = load_nls(p); | ||
301 | if (!hsb->nls_disk) { | 302 | if (!hsb->nls_disk) { |
302 | printk(KERN_ERR "hfs: unable to load codepage \"%s\"\n", p); | 303 | printk(KERN_ERR "hfs: unable to load codepage \"%s\"\n", p); |
303 | kfree(p); | 304 | kfree(p); |
@@ -311,7 +312,8 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
311 | return 0; | 312 | return 0; |
312 | } | 313 | } |
313 | p = match_strdup(&args[0]); | 314 | p = match_strdup(&args[0]); |
314 | hsb->nls_io = load_nls(p); | 315 | if (p) |
316 | hsb->nls_io = load_nls(p); | ||
315 | if (!hsb->nls_io) { | 317 | if (!hsb->nls_io) { |
316 | printk(KERN_ERR "hfs: unable to load iocharset \"%s\"\n", p); | 318 | printk(KERN_ERR "hfs: unable to load iocharset \"%s\"\n", p); |
317 | kfree(p); | 319 | kfree(p); |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index d72d0a8b25aa..9e59537b43d5 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -311,6 +311,10 @@ int hfsplus_delete_cat(u32, struct inode *, struct qstr *); | |||
311 | int hfsplus_rename_cat(u32, struct inode *, struct qstr *, | 311 | int hfsplus_rename_cat(u32, struct inode *, struct qstr *, |
312 | struct inode *, struct qstr *); | 312 | struct inode *, struct qstr *); |
313 | 313 | ||
314 | /* dir.c */ | ||
315 | extern const struct inode_operations hfsplus_dir_inode_operations; | ||
316 | extern const struct file_operations hfsplus_dir_operations; | ||
317 | |||
314 | /* extents.c */ | 318 | /* extents.c */ |
315 | int hfsplus_ext_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *); | 319 | int hfsplus_ext_cmp_key(const hfsplus_btree_key *, const hfsplus_btree_key *); |
316 | void hfsplus_ext_write_extent(struct inode *); | 320 | void hfsplus_ext_write_extent(struct inode *); |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 37744cf3706a..d53b2af91c25 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -278,9 +278,6 @@ static int hfsplus_file_release(struct inode *inode, struct file *file) | |||
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
280 | 280 | ||
281 | extern const struct inode_operations hfsplus_dir_inode_operations; | ||
282 | extern struct file_operations hfsplus_dir_operations; | ||
283 | |||
284 | static const struct inode_operations hfsplus_file_inode_operations = { | 281 | static const struct inode_operations hfsplus_file_inode_operations = { |
285 | .lookup = hfsplus_file_lookup, | 282 | .lookup = hfsplus_file_lookup, |
286 | .truncate = hfsplus_file_truncate, | 283 | .truncate = hfsplus_file_truncate, |
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index dc64fac00831..9997cbf8beb5 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c | |||
@@ -132,7 +132,8 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | p = match_strdup(&args[0]); | 134 | p = match_strdup(&args[0]); |
135 | sbi->nls = load_nls(p); | 135 | if (p) |
136 | sbi->nls = load_nls(p); | ||
136 | if (!sbi->nls) { | 137 | if (!sbi->nls) { |
137 | printk(KERN_ERR "hfs: unable to load nls mapping \"%s\"\n", p); | 138 | printk(KERN_ERR "hfs: unable to load nls mapping \"%s\"\n", p); |
138 | kfree(p); | 139 | kfree(p); |
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 72cab78f0509..175d08eacc86 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
@@ -47,7 +47,7 @@ static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) | |||
47 | return 0; | 47 | return 0; |
48 | wd->ablk_start = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ABLKSTART)); | 48 | wd->ablk_start = be16_to_cpu(*(__be16 *)(bufptr + HFSP_WRAPOFF_ABLKSTART)); |
49 | 49 | ||
50 | extent = be32_to_cpu(get_unaligned((__be32 *)(bufptr + HFSP_WRAPOFF_EMBEDEXT))); | 50 | extent = get_unaligned_be32(bufptr + HFSP_WRAPOFF_EMBEDEXT); |
51 | wd->embed_start = (extent >> 16) & 0xFFFF; | 51 | wd->embed_start = (extent >> 16) & 0xFFFF; |
52 | wd->embed_count = extent & 0xFFFF; | 52 | wd->embed_count = extent & 0xFFFF; |
53 | 53 | ||
diff --git a/fs/inode.c b/fs/inode.c index 27ee1af50d02..bf6478130424 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -495,8 +495,7 @@ static struct inode * find_inode(struct super_block * sb, struct hlist_head *hea | |||
495 | struct inode * inode = NULL; | 495 | struct inode * inode = NULL; |
496 | 496 | ||
497 | repeat: | 497 | repeat: |
498 | hlist_for_each (node, head) { | 498 | hlist_for_each_entry(inode, node, head, i_hash) { |
499 | inode = hlist_entry(node, struct inode, i_hash); | ||
500 | if (inode->i_sb != sb) | 499 | if (inode->i_sb != sb) |
501 | continue; | 500 | continue; |
502 | if (!test(inode, data)) | 501 | if (!test(inode, data)) |
@@ -520,8 +519,7 @@ static struct inode * find_inode_fast(struct super_block * sb, struct hlist_head | |||
520 | struct inode * inode = NULL; | 519 | struct inode * inode = NULL; |
521 | 520 | ||
522 | repeat: | 521 | repeat: |
523 | hlist_for_each (node, head) { | 522 | hlist_for_each_entry(inode, node, head, i_hash) { |
524 | inode = hlist_entry(node, struct inode, i_hash); | ||
525 | if (inode->i_ino != ino) | 523 | if (inode->i_ino != ino) |
526 | continue; | 524 | continue; |
527 | if (inode->i_sb != sb) | 525 | if (inode->i_sb != sb) |
diff --git a/fs/inotify_user.c b/fs/inotify_user.c index 7b94a1e3c015..6676c06bb7c1 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c | |||
@@ -598,7 +598,7 @@ asmlinkage long sys_inotify_init(void) | |||
598 | } | 598 | } |
599 | 599 | ||
600 | ih = inotify_init(&inotify_user_ops); | 600 | ih = inotify_init(&inotify_user_ops); |
601 | if (unlikely(IS_ERR(ih))) { | 601 | if (IS_ERR(ih)) { |
602 | ret = PTR_ERR(ih); | 602 | ret = PTR_ERR(ih); |
603 | goto out_free_dev; | 603 | goto out_free_dev; |
604 | } | 604 | } |
diff --git a/fs/ioctl.c b/fs/ioctl.c index f32fbde2175e..7db32b3382d3 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
@@ -28,8 +28,8 @@ | |||
28 | * | 28 | * |
29 | * Returns 0 on success, -errno on error. | 29 | * Returns 0 on success, -errno on error. |
30 | */ | 30 | */ |
31 | long vfs_ioctl(struct file *filp, unsigned int cmd, | 31 | static long vfs_ioctl(struct file *filp, unsigned int cmd, |
32 | unsigned long arg) | 32 | unsigned long arg) |
33 | { | 33 | { |
34 | int error = -ENOTTY; | 34 | int error = -ENOTTY; |
35 | 35 | ||
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h index d1bdf8adb351..ccbf72faf27a 100644 --- a/fs/isofs/isofs.h +++ b/fs/isofs/isofs.h | |||
@@ -78,29 +78,29 @@ static inline int isonum_712(char *p) | |||
78 | } | 78 | } |
79 | static inline unsigned int isonum_721(char *p) | 79 | static inline unsigned int isonum_721(char *p) |
80 | { | 80 | { |
81 | return le16_to_cpu(get_unaligned((__le16 *)p)); | 81 | return get_unaligned_le16(p); |
82 | } | 82 | } |
83 | static inline unsigned int isonum_722(char *p) | 83 | static inline unsigned int isonum_722(char *p) |
84 | { | 84 | { |
85 | return be16_to_cpu(get_unaligned((__le16 *)p)); | 85 | return get_unaligned_be16(p); |
86 | } | 86 | } |
87 | static inline unsigned int isonum_723(char *p) | 87 | static inline unsigned int isonum_723(char *p) |
88 | { | 88 | { |
89 | /* Ignore bigendian datum due to broken mastering programs */ | 89 | /* Ignore bigendian datum due to broken mastering programs */ |
90 | return le16_to_cpu(get_unaligned((__le16 *)p)); | 90 | return get_unaligned_le16(p); |
91 | } | 91 | } |
92 | static inline unsigned int isonum_731(char *p) | 92 | static inline unsigned int isonum_731(char *p) |
93 | { | 93 | { |
94 | return le32_to_cpu(get_unaligned((__le32 *)p)); | 94 | return get_unaligned_le32(p); |
95 | } | 95 | } |
96 | static inline unsigned int isonum_732(char *p) | 96 | static inline unsigned int isonum_732(char *p) |
97 | { | 97 | { |
98 | return be32_to_cpu(get_unaligned((__le32 *)p)); | 98 | return get_unaligned_be32(p); |
99 | } | 99 | } |
100 | static inline unsigned int isonum_733(char *p) | 100 | static inline unsigned int isonum_733(char *p) |
101 | { | 101 | { |
102 | /* Ignore bigendian datum due to broken mastering programs */ | 102 | /* Ignore bigendian datum due to broken mastering programs */ |
103 | return le32_to_cpu(get_unaligned((__le32 *)p)); | 103 | return get_unaligned_le32(p); |
104 | } | 104 | } |
105 | extern int iso_date(char *, int); | 105 | extern int iso_date(char *, int); |
106 | 106 | ||
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 954cff001df6..eb7eb6c27bcb 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -904,19 +904,10 @@ static void jbd2_stats_proc_init(journal_t *journal) | |||
904 | snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name)); | 904 | snprintf(name, sizeof(name) - 1, "%s", bdevname(journal->j_dev, name)); |
905 | journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats); | 905 | journal->j_proc_entry = proc_mkdir(name, proc_jbd2_stats); |
906 | if (journal->j_proc_entry) { | 906 | if (journal->j_proc_entry) { |
907 | struct proc_dir_entry *p; | 907 | proc_create_data("history", S_IRUGO, journal->j_proc_entry, |
908 | p = create_proc_entry("history", S_IRUGO, | 908 | &jbd2_seq_history_fops, journal); |
909 | journal->j_proc_entry); | 909 | proc_create_data("info", S_IRUGO, journal->j_proc_entry, |
910 | if (p) { | 910 | &jbd2_seq_info_fops, journal); |
911 | p->proc_fops = &jbd2_seq_history_fops; | ||
912 | p->data = journal; | ||
913 | p = create_proc_entry("info", S_IRUGO, | ||
914 | journal->j_proc_entry); | ||
915 | if (p) { | ||
916 | p->proc_fops = &jbd2_seq_info_fops; | ||
917 | p->data = journal; | ||
918 | } | ||
919 | } | ||
920 | } | 911 | } |
921 | } | 912 | } |
922 | 913 | ||
diff --git a/fs/jfs/jfs_debug.c b/fs/jfs/jfs_debug.c index 887f5759e536..bf6ab19b86ee 100644 --- a/fs/jfs/jfs_debug.c +++ b/fs/jfs/jfs_debug.c | |||
@@ -89,7 +89,7 @@ void jfs_proc_init(void) | |||
89 | { | 89 | { |
90 | int i; | 90 | int i; |
91 | 91 | ||
92 | if (!(base = proc_mkdir("jfs", proc_root_fs))) | 92 | if (!(base = proc_mkdir("fs/jfs", NULL))) |
93 | return; | 93 | return; |
94 | base->owner = THIS_MODULE; | 94 | base->owner = THIS_MODULE; |
95 | 95 | ||
@@ -109,7 +109,7 @@ void jfs_proc_clean(void) | |||
109 | if (base) { | 109 | if (base) { |
110 | for (i = 0; i < NPROCENT; i++) | 110 | for (i = 0; i < NPROCENT; i++) |
111 | remove_proc_entry(Entries[i].name, base); | 111 | remove_proc_entry(Entries[i].name, base); |
112 | remove_proc_entry("jfs", proc_root_fs); | 112 | remove_proc_entry("fs/jfs", NULL); |
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
diff --git a/fs/namei.c b/fs/namei.c index e179f71bfcb0..32fd9655485b 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/capability.h> | 30 | #include <linux/capability.h> |
31 | #include <linux/file.h> | 31 | #include <linux/file.h> |
32 | #include <linux/fcntl.h> | 32 | #include <linux/fcntl.h> |
33 | #include <linux/device_cgroup.h> | ||
33 | #include <asm/namei.h> | 34 | #include <asm/namei.h> |
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
35 | 36 | ||
@@ -281,6 +282,10 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
281 | if (retval) | 282 | if (retval) |
282 | return retval; | 283 | return retval; |
283 | 284 | ||
285 | retval = devcgroup_inode_permission(inode, mask); | ||
286 | if (retval) | ||
287 | return retval; | ||
288 | |||
284 | return security_inode_permission(inode, mask, nd); | 289 | return security_inode_permission(inode, mask, nd); |
285 | } | 290 | } |
286 | 291 | ||
@@ -2028,6 +2033,10 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
2028 | if (!dir->i_op || !dir->i_op->mknod) | 2033 | if (!dir->i_op || !dir->i_op->mknod) |
2029 | return -EPERM; | 2034 | return -EPERM; |
2030 | 2035 | ||
2036 | error = devcgroup_inode_mknod(mode, dev); | ||
2037 | if (error) | ||
2038 | return error; | ||
2039 | |||
2031 | error = security_inode_mknod(dir, dentry, mode, dev); | 2040 | error = security_inode_mknod(dir, dentry, mode, dev); |
2032 | if (error) | 2041 | if (error) |
2033 | return error; | 2042 | return error; |
diff --git a/fs/namespace.c b/fs/namespace.c index fe376805cf5f..061e5edb4d27 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1176,17 +1176,6 @@ static int mount_is_safe(struct nameidata *nd) | |||
1176 | #endif | 1176 | #endif |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | static int lives_below_in_same_fs(struct dentry *d, struct dentry *dentry) | ||
1180 | { | ||
1181 | while (1) { | ||
1182 | if (d == dentry) | ||
1183 | return 1; | ||
1184 | if (d == NULL || d == d->d_parent) | ||
1185 | return 0; | ||
1186 | d = d->d_parent; | ||
1187 | } | ||
1188 | } | ||
1189 | |||
1190 | struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, | 1179 | struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, |
1191 | int flag) | 1180 | int flag) |
1192 | { | 1181 | { |
@@ -1203,7 +1192,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, | |||
1203 | 1192 | ||
1204 | p = mnt; | 1193 | p = mnt; |
1205 | list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) { | 1194 | list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) { |
1206 | if (!lives_below_in_same_fs(r->mnt_mountpoint, dentry)) | 1195 | if (!is_subdir(r->mnt_mountpoint, dentry)) |
1207 | continue; | 1196 | continue; |
1208 | 1197 | ||
1209 | for (s = r; s; s = next_mnt(s, r)) { | 1198 | for (s = r; s; s = next_mnt(s, r)) { |
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c index df6d60bdfcd3..97645f112114 100644 --- a/fs/ncpfs/ncplib_kernel.c +++ b/fs/ncpfs/ncplib_kernel.c | |||
@@ -102,48 +102,47 @@ static inline void ncp_init_request_s(struct ncp_server *server, int subfunction | |||
102 | } | 102 | } |
103 | 103 | ||
104 | static inline char * | 104 | static inline char * |
105 | ncp_reply_data(struct ncp_server *server, int offset) | 105 | ncp_reply_data(struct ncp_server *server, int offset) |
106 | { | 106 | { |
107 | return &(server->packet[sizeof(struct ncp_reply_header) + offset]); | 107 | return &(server->packet[sizeof(struct ncp_reply_header) + offset]); |
108 | } | 108 | } |
109 | 109 | ||
110 | static inline __u8 BVAL(void* data) | 110 | static inline u8 BVAL(void *data) |
111 | { | 111 | { |
112 | return get_unaligned((__u8*)data); | 112 | return *(u8 *)data; |
113 | } | 113 | } |
114 | 114 | ||
115 | static __u8 | 115 | static u8 ncp_reply_byte(struct ncp_server *server, int offset) |
116 | ncp_reply_byte(struct ncp_server *server, int offset) | ||
117 | { | 116 | { |
118 | return get_unaligned((__u8 *) ncp_reply_data(server, offset)); | 117 | return *(u8 *)ncp_reply_data(server, offset); |
119 | } | 118 | } |
120 | 119 | ||
121 | static inline __u16 WVAL_LH(void* data) | 120 | static inline u16 WVAL_LH(void *data) |
122 | { | 121 | { |
123 | return le16_to_cpu(get_unaligned((__le16*)data)); | 122 | return get_unaligned_le16(data); |
124 | } | 123 | } |
125 | 124 | ||
126 | static __u16 | 125 | static u16 |
127 | ncp_reply_le16(struct ncp_server *server, int offset) | 126 | ncp_reply_le16(struct ncp_server *server, int offset) |
128 | { | 127 | { |
129 | return le16_to_cpu(get_unaligned((__le16 *) ncp_reply_data(server, offset))); | 128 | return get_unaligned_le16(ncp_reply_data(server, offset)); |
130 | } | 129 | } |
131 | 130 | ||
132 | static __u16 | 131 | static u16 |
133 | ncp_reply_be16(struct ncp_server *server, int offset) | 132 | ncp_reply_be16(struct ncp_server *server, int offset) |
134 | { | 133 | { |
135 | return be16_to_cpu(get_unaligned((__be16 *) ncp_reply_data(server, offset))); | 134 | return get_unaligned_be16(ncp_reply_data(server, offset)); |
136 | } | 135 | } |
137 | 136 | ||
138 | static inline __u32 DVAL_LH(void* data) | 137 | static inline u32 DVAL_LH(void *data) |
139 | { | 138 | { |
140 | return le32_to_cpu(get_unaligned((__le32*)data)); | 139 | return get_unaligned_le32(data); |
141 | } | 140 | } |
142 | 141 | ||
143 | static __le32 | 142 | static __le32 |
144 | ncp_reply_dword(struct ncp_server *server, int offset) | 143 | ncp_reply_dword(struct ncp_server *server, int offset) |
145 | { | 144 | { |
146 | return get_unaligned((__le32 *) ncp_reply_data(server, offset)); | 145 | return get_unaligned((__le32 *)ncp_reply_data(server, offset)); |
147 | } | 146 | } |
148 | 147 | ||
149 | static inline __u32 ncp_reply_dword_lh(struct ncp_server* server, int offset) { | 148 | static inline __u32 ncp_reply_dword_lh(struct ncp_server* server, int offset) { |
@@ -1006,8 +1005,8 @@ ncp_read_bounce(struct ncp_server *server, const char *file_id, | |||
1006 | result = ncp_request2(server, 72, bounce, bufsize); | 1005 | result = ncp_request2(server, 72, bounce, bufsize); |
1007 | ncp_unlock_server(server); | 1006 | ncp_unlock_server(server); |
1008 | if (!result) { | 1007 | if (!result) { |
1009 | int len = be16_to_cpu(get_unaligned((__be16*)((char*)bounce + | 1008 | int len = get_unaligned_be16((char *)bounce + |
1010 | sizeof(struct ncp_reply_header)))); | 1009 | sizeof(struct ncp_reply_header)); |
1011 | result = -EIO; | 1010 | result = -EIO; |
1012 | if (len <= to_read) { | 1011 | if (len <= to_read) { |
1013 | char* source; | 1012 | char* source; |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index f2f3b284e6dd..89ac5bb0401c 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -1321,6 +1321,7 @@ static const struct file_operations nfs_server_list_fops = { | |||
1321 | .read = seq_read, | 1321 | .read = seq_read, |
1322 | .llseek = seq_lseek, | 1322 | .llseek = seq_lseek, |
1323 | .release = seq_release, | 1323 | .release = seq_release, |
1324 | .owner = THIS_MODULE, | ||
1324 | }; | 1325 | }; |
1325 | 1326 | ||
1326 | static int nfs_volume_list_open(struct inode *inode, struct file *file); | 1327 | static int nfs_volume_list_open(struct inode *inode, struct file *file); |
@@ -1341,6 +1342,7 @@ static const struct file_operations nfs_volume_list_fops = { | |||
1341 | .read = seq_read, | 1342 | .read = seq_read, |
1342 | .llseek = seq_lseek, | 1343 | .llseek = seq_lseek, |
1343 | .release = seq_release, | 1344 | .release = seq_release, |
1345 | .owner = THIS_MODULE, | ||
1344 | }; | 1346 | }; |
1345 | 1347 | ||
1346 | /* | 1348 | /* |
@@ -1500,33 +1502,29 @@ int __init nfs_fs_proc_init(void) | |||
1500 | { | 1502 | { |
1501 | struct proc_dir_entry *p; | 1503 | struct proc_dir_entry *p; |
1502 | 1504 | ||
1503 | proc_fs_nfs = proc_mkdir("nfsfs", proc_root_fs); | 1505 | proc_fs_nfs = proc_mkdir("fs/nfsfs", NULL); |
1504 | if (!proc_fs_nfs) | 1506 | if (!proc_fs_nfs) |
1505 | goto error_0; | 1507 | goto error_0; |
1506 | 1508 | ||
1507 | proc_fs_nfs->owner = THIS_MODULE; | 1509 | proc_fs_nfs->owner = THIS_MODULE; |
1508 | 1510 | ||
1509 | /* a file of servers with which we're dealing */ | 1511 | /* a file of servers with which we're dealing */ |
1510 | p = create_proc_entry("servers", S_IFREG|S_IRUGO, proc_fs_nfs); | 1512 | p = proc_create("servers", S_IFREG|S_IRUGO, |
1513 | proc_fs_nfs, &nfs_server_list_fops); | ||
1511 | if (!p) | 1514 | if (!p) |
1512 | goto error_1; | 1515 | goto error_1; |
1513 | 1516 | ||
1514 | p->proc_fops = &nfs_server_list_fops; | ||
1515 | p->owner = THIS_MODULE; | ||
1516 | |||
1517 | /* a file of volumes that we have mounted */ | 1517 | /* a file of volumes that we have mounted */ |
1518 | p = create_proc_entry("volumes", S_IFREG|S_IRUGO, proc_fs_nfs); | 1518 | p = proc_create("volumes", S_IFREG|S_IRUGO, |
1519 | proc_fs_nfs, &nfs_volume_list_fops); | ||
1519 | if (!p) | 1520 | if (!p) |
1520 | goto error_2; | 1521 | goto error_2; |
1521 | |||
1522 | p->proc_fops = &nfs_volume_list_fops; | ||
1523 | p->owner = THIS_MODULE; | ||
1524 | return 0; | 1522 | return 0; |
1525 | 1523 | ||
1526 | error_2: | 1524 | error_2: |
1527 | remove_proc_entry("servers", proc_fs_nfs); | 1525 | remove_proc_entry("servers", proc_fs_nfs); |
1528 | error_1: | 1526 | error_1: |
1529 | remove_proc_entry("nfsfs", proc_root_fs); | 1527 | remove_proc_entry("fs/nfsfs", NULL); |
1530 | error_0: | 1528 | error_0: |
1531 | return -ENOMEM; | 1529 | return -ENOMEM; |
1532 | } | 1530 | } |
@@ -1538,7 +1536,7 @@ void nfs_fs_proc_exit(void) | |||
1538 | { | 1536 | { |
1539 | remove_proc_entry("volumes", proc_fs_nfs); | 1537 | remove_proc_entry("volumes", proc_fs_nfs); |
1540 | remove_proc_entry("servers", proc_fs_nfs); | 1538 | remove_proc_entry("servers", proc_fs_nfs); |
1541 | remove_proc_entry("nfsfs", proc_root_fs); | 1539 | remove_proc_entry("fs/nfsfs", NULL); |
1542 | } | 1540 | } |
1543 | 1541 | ||
1544 | #endif /* CONFIG_PROC_FS */ | 1542 | #endif /* CONFIG_PROC_FS */ |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 42f3820ee8f5..5ac00c4fee91 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -169,6 +169,7 @@ static const struct file_operations exports_operations = { | |||
169 | .read = seq_read, | 169 | .read = seq_read, |
170 | .llseek = seq_lseek, | 170 | .llseek = seq_lseek, |
171 | .release = seq_release, | 171 | .release = seq_release, |
172 | .owner = THIS_MODULE, | ||
172 | }; | 173 | }; |
173 | 174 | ||
174 | /*----------------------------------------------------------------------------*/ | 175 | /*----------------------------------------------------------------------------*/ |
@@ -801,10 +802,9 @@ static int create_proc_exports_entry(void) | |||
801 | entry = proc_mkdir("fs/nfs", NULL); | 802 | entry = proc_mkdir("fs/nfs", NULL); |
802 | if (!entry) | 803 | if (!entry) |
803 | return -ENOMEM; | 804 | return -ENOMEM; |
804 | entry = create_proc_entry("fs/nfs/exports", 0, NULL); | 805 | entry = proc_create("exports", 0, entry, &exports_operations); |
805 | if (!entry) | 806 | if (!entry) |
806 | return -ENOMEM; | 807 | return -ENOMEM; |
807 | entry->proc_fops = &exports_operations; | ||
808 | return 0; | 808 | return 0; |
809 | } | 809 | } |
810 | #else /* CONFIG_PROC_FS */ | 810 | #else /* CONFIG_PROC_FS */ |
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 2ad5c8b104b9..790defb847e7 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c | |||
@@ -1191,7 +1191,7 @@ static int ntfs_mft_bitmap_find_and_alloc_free_rec_nolock(ntfs_volume *vol, | |||
1191 | if (size) { | 1191 | if (size) { |
1192 | page = ntfs_map_page(mftbmp_mapping, | 1192 | page = ntfs_map_page(mftbmp_mapping, |
1193 | ofs >> PAGE_CACHE_SHIFT); | 1193 | ofs >> PAGE_CACHE_SHIFT); |
1194 | if (unlikely(IS_ERR(page))) { | 1194 | if (IS_ERR(page)) { |
1195 | ntfs_error(vol->sb, "Failed to read mft " | 1195 | ntfs_error(vol->sb, "Failed to read mft " |
1196 | "bitmap, aborting."); | 1196 | "bitmap, aborting."); |
1197 | return PTR_ERR(page); | 1197 | return PTR_ERR(page); |
@@ -2118,7 +2118,7 @@ static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no) | |||
2118 | } | 2118 | } |
2119 | /* Read, map, and pin the page containing the mft record. */ | 2119 | /* Read, map, and pin the page containing the mft record. */ |
2120 | page = ntfs_map_page(mft_vi->i_mapping, index); | 2120 | page = ntfs_map_page(mft_vi->i_mapping, index); |
2121 | if (unlikely(IS_ERR(page))) { | 2121 | if (IS_ERR(page)) { |
2122 | ntfs_error(vol->sb, "Failed to map page containing mft record " | 2122 | ntfs_error(vol->sb, "Failed to map page containing mft record " |
2123 | "to format 0x%llx.", (long long)mft_no); | 2123 | "to format 0x%llx.", (long long)mft_no); |
2124 | return PTR_ERR(page); | 2124 | return PTR_ERR(page); |
@@ -2519,7 +2519,7 @@ mft_rec_already_initialized: | |||
2519 | ofs = (bit << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; | 2519 | ofs = (bit << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; |
2520 | /* Read, map, and pin the page containing the mft record. */ | 2520 | /* Read, map, and pin the page containing the mft record. */ |
2521 | page = ntfs_map_page(vol->mft_ino->i_mapping, index); | 2521 | page = ntfs_map_page(vol->mft_ino->i_mapping, index); |
2522 | if (unlikely(IS_ERR(page))) { | 2522 | if (IS_ERR(page)) { |
2523 | ntfs_error(vol->sb, "Failed to map page containing allocated " | 2523 | ntfs_error(vol->sb, "Failed to map page containing allocated " |
2524 | "mft record 0x%llx.", (long long)bit); | 2524 | "mft record 0x%llx.", (long long)bit); |
2525 | err = PTR_ERR(page); | 2525 | err = PTR_ERR(page); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index c5e412a00b17..fcf02f2deeba 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -195,12 +195,32 @@ static int proc_root_link(struct inode *inode, struct path *path) | |||
195 | return result; | 195 | return result; |
196 | } | 196 | } |
197 | 197 | ||
198 | #define MAY_PTRACE(task) \ | 198 | /* |
199 | (task == current || \ | 199 | * Return zero if current may access user memory in @task, -error if not. |
200 | (task->parent == current && \ | 200 | */ |
201 | (task->ptrace & PT_PTRACED) && \ | 201 | static int check_mem_permission(struct task_struct *task) |
202 | (task_is_stopped_or_traced(task)) && \ | 202 | { |
203 | security_ptrace(current,task) == 0)) | 203 | /* |
204 | * A task can always look at itself, in case it chooses | ||
205 | * to use system calls instead of load instructions. | ||
206 | */ | ||
207 | if (task == current) | ||
208 | return 0; | ||
209 | |||
210 | /* | ||
211 | * If current is actively ptrace'ing, and would also be | ||
212 | * permitted to freshly attach with ptrace now, permit it. | ||
213 | */ | ||
214 | if (task->parent == current && (task->ptrace & PT_PTRACED) && | ||
215 | task_is_stopped_or_traced(task) && | ||
216 | ptrace_may_attach(task)) | ||
217 | return 0; | ||
218 | |||
219 | /* | ||
220 | * Noone else is allowed. | ||
221 | */ | ||
222 | return -EPERM; | ||
223 | } | ||
204 | 224 | ||
205 | struct mm_struct *mm_for_maps(struct task_struct *task) | 225 | struct mm_struct *mm_for_maps(struct task_struct *task) |
206 | { | 226 | { |
@@ -722,7 +742,7 @@ static ssize_t mem_read(struct file * file, char __user * buf, | |||
722 | if (!task) | 742 | if (!task) |
723 | goto out_no_task; | 743 | goto out_no_task; |
724 | 744 | ||
725 | if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) | 745 | if (check_mem_permission(task)) |
726 | goto out; | 746 | goto out; |
727 | 747 | ||
728 | ret = -ENOMEM; | 748 | ret = -ENOMEM; |
@@ -748,7 +768,7 @@ static ssize_t mem_read(struct file * file, char __user * buf, | |||
748 | 768 | ||
749 | this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; | 769 | this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count; |
750 | retval = access_process_vm(task, src, page, this_len, 0); | 770 | retval = access_process_vm(task, src, page, this_len, 0); |
751 | if (!retval || !MAY_PTRACE(task) || !ptrace_may_attach(task)) { | 771 | if (!retval || check_mem_permission(task)) { |
752 | if (!ret) | 772 | if (!ret) |
753 | ret = -EIO; | 773 | ret = -EIO; |
754 | break; | 774 | break; |
@@ -792,7 +812,7 @@ static ssize_t mem_write(struct file * file, const char __user *buf, | |||
792 | if (!task) | 812 | if (!task) |
793 | goto out_no_task; | 813 | goto out_no_task; |
794 | 814 | ||
795 | if (!MAY_PTRACE(task) || !ptrace_may_attach(task)) | 815 | if (check_mem_permission(task)) |
796 | goto out; | 816 | goto out; |
797 | 817 | ||
798 | copied = -ENOMEM; | 818 | copied = -ENOMEM; |
@@ -1181,6 +1201,81 @@ static const struct file_operations proc_pid_sched_operations = { | |||
1181 | 1201 | ||
1182 | #endif | 1202 | #endif |
1183 | 1203 | ||
1204 | /* | ||
1205 | * We added or removed a vma mapping the executable. The vmas are only mapped | ||
1206 | * during exec and are not mapped with the mmap system call. | ||
1207 | * Callers must hold down_write() on the mm's mmap_sem for these | ||
1208 | */ | ||
1209 | void added_exe_file_vma(struct mm_struct *mm) | ||
1210 | { | ||
1211 | mm->num_exe_file_vmas++; | ||
1212 | } | ||
1213 | |||
1214 | void removed_exe_file_vma(struct mm_struct *mm) | ||
1215 | { | ||
1216 | mm->num_exe_file_vmas--; | ||
1217 | if ((mm->num_exe_file_vmas == 0) && mm->exe_file){ | ||
1218 | fput(mm->exe_file); | ||
1219 | mm->exe_file = NULL; | ||
1220 | } | ||
1221 | |||
1222 | } | ||
1223 | |||
1224 | void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file) | ||
1225 | { | ||
1226 | if (new_exe_file) | ||
1227 | get_file(new_exe_file); | ||
1228 | if (mm->exe_file) | ||
1229 | fput(mm->exe_file); | ||
1230 | mm->exe_file = new_exe_file; | ||
1231 | mm->num_exe_file_vmas = 0; | ||
1232 | } | ||
1233 | |||
1234 | struct file *get_mm_exe_file(struct mm_struct *mm) | ||
1235 | { | ||
1236 | struct file *exe_file; | ||
1237 | |||
1238 | /* We need mmap_sem to protect against races with removal of | ||
1239 | * VM_EXECUTABLE vmas */ | ||
1240 | down_read(&mm->mmap_sem); | ||
1241 | exe_file = mm->exe_file; | ||
1242 | if (exe_file) | ||
1243 | get_file(exe_file); | ||
1244 | up_read(&mm->mmap_sem); | ||
1245 | return exe_file; | ||
1246 | } | ||
1247 | |||
1248 | void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm) | ||
1249 | { | ||
1250 | /* It's safe to write the exe_file pointer without exe_file_lock because | ||
1251 | * this is called during fork when the task is not yet in /proc */ | ||
1252 | newmm->exe_file = get_mm_exe_file(oldmm); | ||
1253 | } | ||
1254 | |||
1255 | static int proc_exe_link(struct inode *inode, struct path *exe_path) | ||
1256 | { | ||
1257 | struct task_struct *task; | ||
1258 | struct mm_struct *mm; | ||
1259 | struct file *exe_file; | ||
1260 | |||
1261 | task = get_proc_task(inode); | ||
1262 | if (!task) | ||
1263 | return -ENOENT; | ||
1264 | mm = get_task_mm(task); | ||
1265 | put_task_struct(task); | ||
1266 | if (!mm) | ||
1267 | return -ENOENT; | ||
1268 | exe_file = get_mm_exe_file(mm); | ||
1269 | mmput(mm); | ||
1270 | if (exe_file) { | ||
1271 | *exe_path = exe_file->f_path; | ||
1272 | path_get(&exe_file->f_path); | ||
1273 | fput(exe_file); | ||
1274 | return 0; | ||
1275 | } else | ||
1276 | return -ENOENT; | ||
1277 | } | ||
1278 | |||
1184 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | 1279 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) |
1185 | { | 1280 | { |
1186 | struct inode *inode = dentry->d_inode; | 1281 | struct inode *inode = dentry->d_inode; |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index a36ad3c75cf4..9d53b39a9cf8 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -69,12 +69,7 @@ proc_file_read(struct file *file, char __user *buf, size_t nbytes, | |||
69 | count = min_t(size_t, PROC_BLOCK_SIZE, nbytes); | 69 | count = min_t(size_t, PROC_BLOCK_SIZE, nbytes); |
70 | 70 | ||
71 | start = NULL; | 71 | start = NULL; |
72 | if (dp->get_info) { | 72 | if (dp->read_proc) { |
73 | /* Handle old net routines */ | ||
74 | n = dp->get_info(page, &start, *ppos, count); | ||
75 | if (n < count) | ||
76 | eof = 1; | ||
77 | } else if (dp->read_proc) { | ||
78 | /* | 73 | /* |
79 | * How to be a proc read function | 74 | * How to be a proc read function |
80 | * ------------------------------ | 75 | * ------------------------------ |
@@ -277,8 +272,11 @@ static int xlate_proc_name(const char *name, | |||
277 | int len; | 272 | int len; |
278 | int rtn = 0; | 273 | int rtn = 0; |
279 | 274 | ||
275 | de = *ret; | ||
276 | if (!de) | ||
277 | de = &proc_root; | ||
278 | |||
280 | spin_lock(&proc_subdir_lock); | 279 | spin_lock(&proc_subdir_lock); |
281 | de = &proc_root; | ||
282 | while (1) { | 280 | while (1) { |
283 | next = strchr(cp, '/'); | 281 | next = strchr(cp, '/'); |
284 | if (!next) | 282 | if (!next) |
@@ -385,20 +383,18 @@ struct dentry *proc_lookup_de(struct proc_dir_entry *de, struct inode *dir, | |||
385 | 383 | ||
386 | lock_kernel(); | 384 | lock_kernel(); |
387 | spin_lock(&proc_subdir_lock); | 385 | spin_lock(&proc_subdir_lock); |
388 | if (de) { | 386 | for (de = de->subdir; de ; de = de->next) { |
389 | for (de = de->subdir; de ; de = de->next) { | 387 | if (de->namelen != dentry->d_name.len) |
390 | if (de->namelen != dentry->d_name.len) | 388 | continue; |
391 | continue; | 389 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { |
392 | if (!memcmp(dentry->d_name.name, de->name, de->namelen)) { | 390 | unsigned int ino; |
393 | unsigned int ino; | ||
394 | 391 | ||
395 | ino = de->low_ino; | 392 | ino = de->low_ino; |
396 | de_get(de); | 393 | de_get(de); |
397 | spin_unlock(&proc_subdir_lock); | 394 | spin_unlock(&proc_subdir_lock); |
398 | error = -EINVAL; | 395 | error = -EINVAL; |
399 | inode = proc_get_inode(dir->i_sb, ino, de); | 396 | inode = proc_get_inode(dir->i_sb, ino, de); |
400 | goto out_unlock; | 397 | goto out_unlock; |
401 | } | ||
402 | } | 398 | } |
403 | } | 399 | } |
404 | spin_unlock(&proc_subdir_lock); | 400 | spin_unlock(&proc_subdir_lock); |
@@ -410,7 +406,8 @@ out_unlock: | |||
410 | d_add(dentry, inode); | 406 | d_add(dentry, inode); |
411 | return NULL; | 407 | return NULL; |
412 | } | 408 | } |
413 | de_put(de); | 409 | if (de) |
410 | de_put(de); | ||
414 | return ERR_PTR(error); | 411 | return ERR_PTR(error); |
415 | } | 412 | } |
416 | 413 | ||
@@ -440,10 +437,6 @@ int proc_readdir_de(struct proc_dir_entry *de, struct file *filp, void *dirent, | |||
440 | lock_kernel(); | 437 | lock_kernel(); |
441 | 438 | ||
442 | ino = inode->i_ino; | 439 | ino = inode->i_ino; |
443 | if (!de) { | ||
444 | ret = -EINVAL; | ||
445 | goto out; | ||
446 | } | ||
447 | i = filp->f_pos; | 440 | i = filp->f_pos; |
448 | switch (i) { | 441 | switch (i) { |
449 | case 0: | 442 | case 0: |
@@ -582,7 +575,7 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent, | |||
582 | /* make sure name is valid */ | 575 | /* make sure name is valid */ |
583 | if (!name || !strlen(name)) goto out; | 576 | if (!name || !strlen(name)) goto out; |
584 | 577 | ||
585 | if (!(*parent) && xlate_proc_name(name, parent, &fn) != 0) | 578 | if (xlate_proc_name(name, parent, &fn) != 0) |
586 | goto out; | 579 | goto out; |
587 | 580 | ||
588 | /* At this point there must not be any '/' characters beyond *fn */ | 581 | /* At this point there must not be any '/' characters beyond *fn */ |
@@ -682,9 +675,10 @@ struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, | |||
682 | return ent; | 675 | return ent; |
683 | } | 676 | } |
684 | 677 | ||
685 | struct proc_dir_entry *proc_create(const char *name, mode_t mode, | 678 | struct proc_dir_entry *proc_create_data(const char *name, mode_t mode, |
686 | struct proc_dir_entry *parent, | 679 | struct proc_dir_entry *parent, |
687 | const struct file_operations *proc_fops) | 680 | const struct file_operations *proc_fops, |
681 | void *data) | ||
688 | { | 682 | { |
689 | struct proc_dir_entry *pde; | 683 | struct proc_dir_entry *pde; |
690 | nlink_t nlink; | 684 | nlink_t nlink; |
@@ -705,6 +699,7 @@ struct proc_dir_entry *proc_create(const char *name, mode_t mode, | |||
705 | if (!pde) | 699 | if (!pde) |
706 | goto out; | 700 | goto out; |
707 | pde->proc_fops = proc_fops; | 701 | pde->proc_fops = proc_fops; |
702 | pde->data = data; | ||
708 | if (proc_register(parent, pde) < 0) | 703 | if (proc_register(parent, pde) < 0) |
709 | goto out_free; | 704 | goto out_free; |
710 | return pde; | 705 | return pde; |
@@ -734,55 +729,58 @@ void free_proc_entry(struct proc_dir_entry *de) | |||
734 | void remove_proc_entry(const char *name, struct proc_dir_entry *parent) | 729 | void remove_proc_entry(const char *name, struct proc_dir_entry *parent) |
735 | { | 730 | { |
736 | struct proc_dir_entry **p; | 731 | struct proc_dir_entry **p; |
737 | struct proc_dir_entry *de; | 732 | struct proc_dir_entry *de = NULL; |
738 | const char *fn = name; | 733 | const char *fn = name; |
739 | int len; | 734 | int len; |
740 | 735 | ||
741 | if (!parent && xlate_proc_name(name, &parent, &fn) != 0) | 736 | if (xlate_proc_name(name, &parent, &fn) != 0) |
742 | goto out; | 737 | return; |
743 | len = strlen(fn); | 738 | len = strlen(fn); |
744 | 739 | ||
745 | spin_lock(&proc_subdir_lock); | 740 | spin_lock(&proc_subdir_lock); |
746 | for (p = &parent->subdir; *p; p=&(*p)->next ) { | 741 | for (p = &parent->subdir; *p; p=&(*p)->next ) { |
747 | if (!proc_match(len, fn, *p)) | 742 | if (proc_match(len, fn, *p)) { |
748 | continue; | 743 | de = *p; |
749 | de = *p; | 744 | *p = de->next; |
750 | *p = de->next; | 745 | de->next = NULL; |
751 | de->next = NULL; | 746 | break; |
752 | 747 | } | |
753 | spin_lock(&de->pde_unload_lock); | 748 | } |
754 | /* | 749 | spin_unlock(&proc_subdir_lock); |
755 | * Stop accepting new callers into module. If you're | 750 | if (!de) |
756 | * dynamically allocating ->proc_fops, save a pointer somewhere. | 751 | return; |
757 | */ | ||
758 | de->proc_fops = NULL; | ||
759 | /* Wait until all existing callers into module are done. */ | ||
760 | if (de->pde_users > 0) { | ||
761 | DECLARE_COMPLETION_ONSTACK(c); | ||
762 | |||
763 | if (!de->pde_unload_completion) | ||
764 | de->pde_unload_completion = &c; | ||
765 | |||
766 | spin_unlock(&de->pde_unload_lock); | ||
767 | spin_unlock(&proc_subdir_lock); | ||
768 | 752 | ||
769 | wait_for_completion(de->pde_unload_completion); | 753 | spin_lock(&de->pde_unload_lock); |
754 | /* | ||
755 | * Stop accepting new callers into module. If you're | ||
756 | * dynamically allocating ->proc_fops, save a pointer somewhere. | ||
757 | */ | ||
758 | de->proc_fops = NULL; | ||
759 | /* Wait until all existing callers into module are done. */ | ||
760 | if (de->pde_users > 0) { | ||
761 | DECLARE_COMPLETION_ONSTACK(c); | ||
762 | |||
763 | if (!de->pde_unload_completion) | ||
764 | de->pde_unload_completion = &c; | ||
770 | 765 | ||
771 | spin_lock(&proc_subdir_lock); | ||
772 | goto continue_removing; | ||
773 | } | ||
774 | spin_unlock(&de->pde_unload_lock); | 766 | spin_unlock(&de->pde_unload_lock); |
775 | 767 | ||
768 | wait_for_completion(de->pde_unload_completion); | ||
769 | |||
770 | goto continue_removing; | ||
771 | } | ||
772 | spin_unlock(&de->pde_unload_lock); | ||
773 | |||
776 | continue_removing: | 774 | continue_removing: |
777 | if (S_ISDIR(de->mode)) | 775 | if (S_ISDIR(de->mode)) |
778 | parent->nlink--; | 776 | parent->nlink--; |
779 | de->nlink = 0; | 777 | de->nlink = 0; |
780 | WARN_ON(de->subdir); | 778 | if (de->subdir) { |
781 | if (atomic_dec_and_test(&de->count)) | 779 | printk(KERN_WARNING "%s: removing non-empty directory " |
782 | free_proc_entry(de); | 780 | "'%s/%s', leaking at least '%s'\n", __func__, |
783 | break; | 781 | de->parent->name, de->name, de->subdir->name); |
782 | WARN_ON(1); | ||
784 | } | 783 | } |
785 | spin_unlock(&proc_subdir_lock); | 784 | if (atomic_dec_and_test(&de->count)) |
786 | out: | 785 | free_proc_entry(de); |
787 | return; | ||
788 | } | 786 | } |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 82b3a1b5a70b..6f4e8dc97da1 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -25,8 +25,7 @@ | |||
25 | 25 | ||
26 | struct proc_dir_entry *de_get(struct proc_dir_entry *de) | 26 | struct proc_dir_entry *de_get(struct proc_dir_entry *de) |
27 | { | 27 | { |
28 | if (de) | 28 | atomic_inc(&de->count); |
29 | atomic_inc(&de->count); | ||
30 | return de; | 29 | return de; |
31 | } | 30 | } |
32 | 31 | ||
@@ -35,18 +34,16 @@ struct proc_dir_entry *de_get(struct proc_dir_entry *de) | |||
35 | */ | 34 | */ |
36 | void de_put(struct proc_dir_entry *de) | 35 | void de_put(struct proc_dir_entry *de) |
37 | { | 36 | { |
38 | if (de) { | 37 | lock_kernel(); |
39 | lock_kernel(); | 38 | if (!atomic_read(&de->count)) { |
40 | if (!atomic_read(&de->count)) { | 39 | printk("de_put: entry %s already free!\n", de->name); |
41 | printk("de_put: entry %s already free!\n", de->name); | ||
42 | unlock_kernel(); | ||
43 | return; | ||
44 | } | ||
45 | |||
46 | if (atomic_dec_and_test(&de->count)) | ||
47 | free_proc_entry(de); | ||
48 | unlock_kernel(); | 40 | unlock_kernel(); |
41 | return; | ||
49 | } | 42 | } |
43 | |||
44 | if (atomic_dec_and_test(&de->count)) | ||
45 | free_proc_entry(de); | ||
46 | unlock_kernel(); | ||
50 | } | 47 | } |
51 | 48 | ||
52 | /* | 49 | /* |
@@ -392,7 +389,7 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
392 | { | 389 | { |
393 | struct inode * inode; | 390 | struct inode * inode; |
394 | 391 | ||
395 | if (de != NULL && !try_module_get(de->owner)) | 392 | if (!try_module_get(de->owner)) |
396 | goto out_mod; | 393 | goto out_mod; |
397 | 394 | ||
398 | inode = iget_locked(sb, ino); | 395 | inode = iget_locked(sb, ino); |
@@ -402,30 +399,29 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
402 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 399 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
403 | PROC_I(inode)->fd = 0; | 400 | PROC_I(inode)->fd = 0; |
404 | PROC_I(inode)->pde = de; | 401 | PROC_I(inode)->pde = de; |
405 | if (de) { | 402 | |
406 | if (de->mode) { | 403 | if (de->mode) { |
407 | inode->i_mode = de->mode; | 404 | inode->i_mode = de->mode; |
408 | inode->i_uid = de->uid; | 405 | inode->i_uid = de->uid; |
409 | inode->i_gid = de->gid; | 406 | inode->i_gid = de->gid; |
410 | } | 407 | } |
411 | if (de->size) | 408 | if (de->size) |
412 | inode->i_size = de->size; | 409 | inode->i_size = de->size; |
413 | if (de->nlink) | 410 | if (de->nlink) |
414 | inode->i_nlink = de->nlink; | 411 | inode->i_nlink = de->nlink; |
415 | if (de->proc_iops) | 412 | if (de->proc_iops) |
416 | inode->i_op = de->proc_iops; | 413 | inode->i_op = de->proc_iops; |
417 | if (de->proc_fops) { | 414 | if (de->proc_fops) { |
418 | if (S_ISREG(inode->i_mode)) { | 415 | if (S_ISREG(inode->i_mode)) { |
419 | #ifdef CONFIG_COMPAT | 416 | #ifdef CONFIG_COMPAT |
420 | if (!de->proc_fops->compat_ioctl) | 417 | if (!de->proc_fops->compat_ioctl) |
421 | inode->i_fop = | 418 | inode->i_fop = |
422 | &proc_reg_file_ops_no_compat; | 419 | &proc_reg_file_ops_no_compat; |
423 | else | 420 | else |
424 | #endif | 421 | #endif |
425 | inode->i_fop = &proc_reg_file_ops; | 422 | inode->i_fop = &proc_reg_file_ops; |
426 | } else { | 423 | } else { |
427 | inode->i_fop = de->proc_fops; | 424 | inode->i_fop = de->proc_fops; |
428 | } | ||
429 | } | 425 | } |
430 | } | 426 | } |
431 | unlock_new_inode(inode); | 427 | unlock_new_inode(inode); |
@@ -433,8 +429,7 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, | |||
433 | return inode; | 429 | return inode; |
434 | 430 | ||
435 | out_ino: | 431 | out_ino: |
436 | if (de != NULL) | 432 | module_put(de->owner); |
437 | module_put(de->owner); | ||
438 | out_mod: | 433 | out_mod: |
439 | return NULL; | 434 | return NULL; |
440 | } | 435 | } |
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index bc72f5c8c47d..28cbca805905 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/proc_fs.h> | 12 | #include <linux/proc_fs.h> |
13 | 13 | ||
14 | extern struct proc_dir_entry proc_root; | ||
14 | #ifdef CONFIG_PROC_SYSCTL | 15 | #ifdef CONFIG_PROC_SYSCTL |
15 | extern int proc_sys_init(void); | 16 | extern int proc_sys_init(void); |
16 | #else | 17 | #else |
@@ -46,9 +47,6 @@ extern int nommu_vma_show(struct seq_file *, struct vm_area_struct *); | |||
46 | 47 | ||
47 | extern int maps_protect; | 48 | extern int maps_protect; |
48 | 49 | ||
49 | extern void create_seq_entry(char *name, mode_t mode, | ||
50 | const struct file_operations *f); | ||
51 | extern int proc_exe_link(struct inode *, struct path *); | ||
52 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, | 50 | extern int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns, |
53 | struct pid *pid, struct task_struct *task); | 51 | struct pid *pid, struct task_struct *task); |
54 | extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, | 52 | extern int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns, |
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c index 941e95114b5a..79ecd281d2cb 100644 --- a/fs/proc/nommu.c +++ b/fs/proc/nommu.c | |||
@@ -137,7 +137,7 @@ static const struct file_operations proc_nommu_vma_list_operations = { | |||
137 | 137 | ||
138 | static int __init proc_nommu_init(void) | 138 | static int __init proc_nommu_init(void) |
139 | { | 139 | { |
140 | create_seq_entry("maps", S_IRUGO, &proc_nommu_vma_list_operations); | 140 | proc_create("maps", S_IRUGO, NULL, &proc_nommu_vma_list_operations); |
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 441a32f0e5f2..48bcf20cec2f 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -826,14 +826,6 @@ static struct file_operations proc_kpageflags_operations = { | |||
826 | 826 | ||
827 | struct proc_dir_entry *proc_root_kcore; | 827 | struct proc_dir_entry *proc_root_kcore; |
828 | 828 | ||
829 | void create_seq_entry(char *name, mode_t mode, const struct file_operations *f) | ||
830 | { | ||
831 | struct proc_dir_entry *entry; | ||
832 | entry = create_proc_entry(name, mode, NULL); | ||
833 | if (entry) | ||
834 | entry->proc_fops = f; | ||
835 | } | ||
836 | |||
837 | void __init proc_misc_init(void) | 829 | void __init proc_misc_init(void) |
838 | { | 830 | { |
839 | static struct { | 831 | static struct { |
@@ -862,66 +854,52 @@ void __init proc_misc_init(void) | |||
862 | 854 | ||
863 | /* And now for trickier ones */ | 855 | /* And now for trickier ones */ |
864 | #ifdef CONFIG_PRINTK | 856 | #ifdef CONFIG_PRINTK |
865 | { | 857 | proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations); |
866 | struct proc_dir_entry *entry; | ||
867 | entry = create_proc_entry("kmsg", S_IRUSR, &proc_root); | ||
868 | if (entry) | ||
869 | entry->proc_fops = &proc_kmsg_operations; | ||
870 | } | ||
871 | #endif | 858 | #endif |
872 | create_seq_entry("locks", 0, &proc_locks_operations); | 859 | proc_create("locks", 0, NULL, &proc_locks_operations); |
873 | create_seq_entry("devices", 0, &proc_devinfo_operations); | 860 | proc_create("devices", 0, NULL, &proc_devinfo_operations); |
874 | create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations); | 861 | proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations); |
875 | #ifdef CONFIG_BLOCK | 862 | #ifdef CONFIG_BLOCK |
876 | create_seq_entry("partitions", 0, &proc_partitions_operations); | 863 | proc_create("partitions", 0, NULL, &proc_partitions_operations); |
877 | #endif | 864 | #endif |
878 | create_seq_entry("stat", 0, &proc_stat_operations); | 865 | proc_create("stat", 0, NULL, &proc_stat_operations); |
879 | create_seq_entry("interrupts", 0, &proc_interrupts_operations); | 866 | proc_create("interrupts", 0, NULL, &proc_interrupts_operations); |
880 | #ifdef CONFIG_SLABINFO | 867 | #ifdef CONFIG_SLABINFO |
881 | create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); | 868 | proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations); |
882 | #ifdef CONFIG_DEBUG_SLAB_LEAK | 869 | #ifdef CONFIG_DEBUG_SLAB_LEAK |
883 | create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations); | 870 | proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations); |
884 | #endif | 871 | #endif |
885 | #endif | 872 | #endif |
886 | #ifdef CONFIG_MMU | 873 | #ifdef CONFIG_MMU |
887 | proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations); | 874 | proc_create("vmallocinfo", S_IRUSR, NULL, &proc_vmalloc_operations); |
888 | #endif | 875 | #endif |
889 | create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); | 876 | proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations); |
890 | create_seq_entry("pagetypeinfo", S_IRUGO, &pagetypeinfo_file_ops); | 877 | proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops); |
891 | create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); | 878 | proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations); |
892 | create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); | 879 | proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations); |
893 | #ifdef CONFIG_BLOCK | 880 | #ifdef CONFIG_BLOCK |
894 | create_seq_entry("diskstats", 0, &proc_diskstats_operations); | 881 | proc_create("diskstats", 0, NULL, &proc_diskstats_operations); |
895 | #endif | 882 | #endif |
896 | #ifdef CONFIG_MODULES | 883 | #ifdef CONFIG_MODULES |
897 | create_seq_entry("modules", 0, &proc_modules_operations); | 884 | proc_create("modules", 0, NULL, &proc_modules_operations); |
898 | #endif | 885 | #endif |
899 | #ifdef CONFIG_SCHEDSTATS | 886 | #ifdef CONFIG_SCHEDSTATS |
900 | create_seq_entry("schedstat", 0, &proc_schedstat_operations); | 887 | proc_create("schedstat", 0, NULL, &proc_schedstat_operations); |
901 | #endif | 888 | #endif |
902 | #ifdef CONFIG_PROC_KCORE | 889 | #ifdef CONFIG_PROC_KCORE |
903 | proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL); | 890 | proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations); |
904 | if (proc_root_kcore) { | 891 | if (proc_root_kcore) |
905 | proc_root_kcore->proc_fops = &proc_kcore_operations; | ||
906 | proc_root_kcore->size = | 892 | proc_root_kcore->size = |
907 | (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; | 893 | (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE; |
908 | } | ||
909 | #endif | 894 | #endif |
910 | #ifdef CONFIG_PROC_PAGE_MONITOR | 895 | #ifdef CONFIG_PROC_PAGE_MONITOR |
911 | create_seq_entry("kpagecount", S_IRUSR, &proc_kpagecount_operations); | 896 | proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations); |
912 | create_seq_entry("kpageflags", S_IRUSR, &proc_kpageflags_operations); | 897 | proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations); |
913 | #endif | 898 | #endif |
914 | #ifdef CONFIG_PROC_VMCORE | 899 | #ifdef CONFIG_PROC_VMCORE |
915 | proc_vmcore = create_proc_entry("vmcore", S_IRUSR, NULL); | 900 | proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations); |
916 | if (proc_vmcore) | ||
917 | proc_vmcore->proc_fops = &proc_vmcore_operations; | ||
918 | #endif | 901 | #endif |
919 | #ifdef CONFIG_MAGIC_SYSRQ | 902 | #ifdef CONFIG_MAGIC_SYSRQ |
920 | { | 903 | proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations); |
921 | struct proc_dir_entry *entry; | ||
922 | entry = create_proc_entry("sysrq-trigger", S_IWUSR, NULL); | ||
923 | if (entry) | ||
924 | entry->proc_fops = &proc_sysrq_trigger_operations; | ||
925 | } | ||
926 | #endif | 904 | #endif |
927 | } | 905 | } |
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 614c34b6d1c2..5acc001d49f6 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -165,8 +165,8 @@ out: | |||
165 | return err; | 165 | return err; |
166 | } | 166 | } |
167 | 167 | ||
168 | static ssize_t proc_sys_read(struct file *filp, char __user *buf, | 168 | static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, |
169 | size_t count, loff_t *ppos) | 169 | size_t count, loff_t *ppos, int write) |
170 | { | 170 | { |
171 | struct dentry *dentry = filp->f_dentry; | 171 | struct dentry *dentry = filp->f_dentry; |
172 | struct ctl_table_header *head; | 172 | struct ctl_table_header *head; |
@@ -190,12 +190,12 @@ static ssize_t proc_sys_read(struct file *filp, char __user *buf, | |||
190 | * and won't be until we finish. | 190 | * and won't be until we finish. |
191 | */ | 191 | */ |
192 | error = -EPERM; | 192 | error = -EPERM; |
193 | if (sysctl_perm(table, MAY_READ)) | 193 | if (sysctl_perm(head->root, table, write ? MAY_WRITE : MAY_READ)) |
194 | goto out; | 194 | goto out; |
195 | 195 | ||
196 | /* careful: calling conventions are nasty here */ | 196 | /* careful: calling conventions are nasty here */ |
197 | res = count; | 197 | res = count; |
198 | error = table->proc_handler(table, 0, filp, buf, &res, ppos); | 198 | error = table->proc_handler(table, write, filp, buf, &res, ppos); |
199 | if (!error) | 199 | if (!error) |
200 | error = res; | 200 | error = res; |
201 | out: | 201 | out: |
@@ -204,44 +204,16 @@ out: | |||
204 | return error; | 204 | return error; |
205 | } | 205 | } |
206 | 206 | ||
207 | static ssize_t proc_sys_write(struct file *filp, const char __user *buf, | 207 | static ssize_t proc_sys_read(struct file *filp, char __user *buf, |
208 | size_t count, loff_t *ppos) | 208 | size_t count, loff_t *ppos) |
209 | { | 209 | { |
210 | struct dentry *dentry = filp->f_dentry; | 210 | return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 0); |
211 | struct ctl_table_header *head; | 211 | } |
212 | struct ctl_table *table; | ||
213 | ssize_t error; | ||
214 | size_t res; | ||
215 | |||
216 | table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); | ||
217 | /* Has the sysctl entry disappeared on us? */ | ||
218 | error = -ENOENT; | ||
219 | if (!table) | ||
220 | goto out; | ||
221 | |||
222 | /* Has the sysctl entry been replaced by a directory? */ | ||
223 | error = -EISDIR; | ||
224 | if (!table->proc_handler) | ||
225 | goto out; | ||
226 | |||
227 | /* | ||
228 | * At this point we know that the sysctl was not unregistered | ||
229 | * and won't be until we finish. | ||
230 | */ | ||
231 | error = -EPERM; | ||
232 | if (sysctl_perm(table, MAY_WRITE)) | ||
233 | goto out; | ||
234 | |||
235 | /* careful: calling conventions are nasty here */ | ||
236 | res = count; | ||
237 | error = table->proc_handler(table, 1, filp, (char __user *)buf, | ||
238 | &res, ppos); | ||
239 | if (!error) | ||
240 | error = res; | ||
241 | out: | ||
242 | sysctl_head_finish(head); | ||
243 | 212 | ||
244 | return error; | 213 | static ssize_t proc_sys_write(struct file *filp, const char __user *buf, |
214 | size_t count, loff_t *ppos) | ||
215 | { | ||
216 | return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 1); | ||
245 | } | 217 | } |
246 | 218 | ||
247 | 219 | ||
@@ -416,7 +388,7 @@ static int proc_sys_permission(struct inode *inode, int mask, struct nameidata * | |||
416 | goto out; | 388 | goto out; |
417 | 389 | ||
418 | /* Use the permissions on the sysctl table entry */ | 390 | /* Use the permissions on the sysctl table entry */ |
419 | error = sysctl_perm(table, mask); | 391 | error = sysctl_perm(head->root, table, mask); |
420 | out: | 392 | out: |
421 | sysctl_head_finish(head); | 393 | sysctl_head_finish(head); |
422 | return error; | 394 | return error; |
diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c index 49816e00b51a..ac26ccc25f42 100644 --- a/fs/proc/proc_tty.c +++ b/fs/proc/proc_tty.c | |||
@@ -5,7 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <asm/uaccess.h> | 7 | #include <asm/uaccess.h> |
8 | 8 | #include <linux/module.h> | |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
@@ -136,39 +136,54 @@ static const struct file_operations proc_tty_drivers_operations = { | |||
136 | .release = seq_release, | 136 | .release = seq_release, |
137 | }; | 137 | }; |
138 | 138 | ||
139 | /* | 139 | static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos) |
140 | * This is the handler for /proc/tty/ldiscs | ||
141 | */ | ||
142 | static int tty_ldiscs_read_proc(char *page, char **start, off_t off, | ||
143 | int count, int *eof, void *data) | ||
144 | { | 140 | { |
145 | int i; | 141 | return (*pos < NR_LDISCS) ? pos : NULL; |
146 | int len = 0; | 142 | } |
147 | off_t begin = 0; | 143 | |
144 | static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos) | ||
145 | { | ||
146 | (*pos)++; | ||
147 | return (*pos < NR_LDISCS) ? pos : NULL; | ||
148 | } | ||
149 | |||
150 | static void tty_ldiscs_seq_stop(struct seq_file *m, void *v) | ||
151 | { | ||
152 | } | ||
153 | |||
154 | static int tty_ldiscs_seq_show(struct seq_file *m, void *v) | ||
155 | { | ||
156 | int i = *(loff_t *)v; | ||
148 | struct tty_ldisc *ld; | 157 | struct tty_ldisc *ld; |
149 | 158 | ||
150 | for (i=0; i < NR_LDISCS; i++) { | 159 | ld = tty_ldisc_get(i); |
151 | ld = tty_ldisc_get(i); | 160 | if (ld == NULL) |
152 | if (ld == NULL) | ||
153 | continue; | ||
154 | len += sprintf(page+len, "%-10s %2d\n", | ||
155 | ld->name ? ld->name : "???", i); | ||
156 | tty_ldisc_put(i); | ||
157 | if (len+begin > off+count) | ||
158 | break; | ||
159 | if (len+begin < off) { | ||
160 | begin += len; | ||
161 | len = 0; | ||
162 | } | ||
163 | } | ||
164 | if (i >= NR_LDISCS) | ||
165 | *eof = 1; | ||
166 | if (off >= len+begin) | ||
167 | return 0; | 161 | return 0; |
168 | *start = page + (off-begin); | 162 | seq_printf(m, "%-10s %2d\n", ld->name ? ld->name : "???", i); |
169 | return ((count < begin+len-off) ? count : begin+len-off); | 163 | tty_ldisc_put(i); |
164 | return 0; | ||
165 | } | ||
166 | |||
167 | static const struct seq_operations tty_ldiscs_seq_ops = { | ||
168 | .start = tty_ldiscs_seq_start, | ||
169 | .next = tty_ldiscs_seq_next, | ||
170 | .stop = tty_ldiscs_seq_stop, | ||
171 | .show = tty_ldiscs_seq_show, | ||
172 | }; | ||
173 | |||
174 | static int proc_tty_ldiscs_open(struct inode *inode, struct file *file) | ||
175 | { | ||
176 | return seq_open(file, &tty_ldiscs_seq_ops); | ||
170 | } | 177 | } |
171 | 178 | ||
179 | static const struct file_operations tty_ldiscs_proc_fops = { | ||
180 | .owner = THIS_MODULE, | ||
181 | .open = proc_tty_ldiscs_open, | ||
182 | .read = seq_read, | ||
183 | .llseek = seq_lseek, | ||
184 | .release = seq_release, | ||
185 | }; | ||
186 | |||
172 | /* | 187 | /* |
173 | * This function is called by tty_register_driver() to handle | 188 | * This function is called by tty_register_driver() to handle |
174 | * registering the driver's /proc handler into /proc/tty/driver/<foo> | 189 | * registering the driver's /proc handler into /proc/tty/driver/<foo> |
@@ -214,7 +229,6 @@ void proc_tty_unregister_driver(struct tty_driver *driver) | |||
214 | */ | 229 | */ |
215 | void __init proc_tty_init(void) | 230 | void __init proc_tty_init(void) |
216 | { | 231 | { |
217 | struct proc_dir_entry *entry; | ||
218 | if (!proc_mkdir("tty", NULL)) | 232 | if (!proc_mkdir("tty", NULL)) |
219 | return; | 233 | return; |
220 | proc_tty_ldisc = proc_mkdir("tty/ldisc", NULL); | 234 | proc_tty_ldisc = proc_mkdir("tty/ldisc", NULL); |
@@ -224,10 +238,7 @@ void __init proc_tty_init(void) | |||
224 | * password lengths and inter-keystroke timings during password | 238 | * password lengths and inter-keystroke timings during password |
225 | * entry. | 239 | * entry. |
226 | */ | 240 | */ |
227 | proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR | S_IXUSR, NULL); | 241 | proc_tty_driver = proc_mkdir_mode("tty/driver", S_IRUSR|S_IXUSR, NULL); |
228 | 242 | proc_create("tty/ldiscs", 0, NULL, &tty_ldiscs_proc_fops); | |
229 | create_proc_read_entry("tty/ldiscs", 0, NULL, tty_ldiscs_read_proc, NULL); | 243 | proc_create("tty/drivers", 0, NULL, &proc_tty_drivers_operations); |
230 | entry = create_proc_entry("tty/drivers", 0, NULL); | ||
231 | if (entry) | ||
232 | entry->proc_fops = &proc_tty_drivers_operations; | ||
233 | } | 244 | } |
diff --git a/fs/proc/root.c b/fs/proc/root.c index ef0fb57fc9ef..95117538a4f6 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -22,8 +22,6 @@ | |||
22 | 22 | ||
23 | #include "internal.h" | 23 | #include "internal.h" |
24 | 24 | ||
25 | struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver; | ||
26 | |||
27 | static int proc_test_super(struct super_block *sb, void *data) | 25 | static int proc_test_super(struct super_block *sb, void *data) |
28 | { | 26 | { |
29 | return sb->s_fs_info == data; | 27 | return sb->s_fs_info == data; |
@@ -126,8 +124,8 @@ void __init proc_root_init(void) | |||
126 | #ifdef CONFIG_SYSVIPC | 124 | #ifdef CONFIG_SYSVIPC |
127 | proc_mkdir("sysvipc", NULL); | 125 | proc_mkdir("sysvipc", NULL); |
128 | #endif | 126 | #endif |
129 | proc_root_fs = proc_mkdir("fs", NULL); | 127 | proc_mkdir("fs", NULL); |
130 | proc_root_driver = proc_mkdir("driver", NULL); | 128 | proc_mkdir("driver", NULL); |
131 | proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */ | 129 | proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */ |
132 | #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) | 130 | #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) |
133 | /* just give it a mountpoint */ | 131 | /* just give it a mountpoint */ |
@@ -137,7 +135,7 @@ void __init proc_root_init(void) | |||
137 | #ifdef CONFIG_PROC_DEVICETREE | 135 | #ifdef CONFIG_PROC_DEVICETREE |
138 | proc_device_tree_init(); | 136 | proc_device_tree_init(); |
139 | #endif | 137 | #endif |
140 | proc_bus = proc_mkdir("bus", NULL); | 138 | proc_mkdir("bus", NULL); |
141 | proc_sys_init(); | 139 | proc_sys_init(); |
142 | } | 140 | } |
143 | 141 | ||
@@ -232,9 +230,5 @@ void pid_ns_release_proc(struct pid_namespace *ns) | |||
232 | EXPORT_SYMBOL(proc_symlink); | 230 | EXPORT_SYMBOL(proc_symlink); |
233 | EXPORT_SYMBOL(proc_mkdir); | 231 | EXPORT_SYMBOL(proc_mkdir); |
234 | EXPORT_SYMBOL(create_proc_entry); | 232 | EXPORT_SYMBOL(create_proc_entry); |
235 | EXPORT_SYMBOL(proc_create); | 233 | EXPORT_SYMBOL(proc_create_data); |
236 | EXPORT_SYMBOL(remove_proc_entry); | 234 | EXPORT_SYMBOL(remove_proc_entry); |
237 | EXPORT_SYMBOL(proc_root); | ||
238 | EXPORT_SYMBOL(proc_root_fs); | ||
239 | EXPORT_SYMBOL(proc_bus); | ||
240 | EXPORT_SYMBOL(proc_root_driver); | ||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 7415eeb7cc3a..e2b8e769f510 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -75,40 +75,6 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, | |||
75 | return mm->total_vm; | 75 | return mm->total_vm; |
76 | } | 76 | } |
77 | 77 | ||
78 | int proc_exe_link(struct inode *inode, struct path *path) | ||
79 | { | ||
80 | struct vm_area_struct * vma; | ||
81 | int result = -ENOENT; | ||
82 | struct task_struct *task = get_proc_task(inode); | ||
83 | struct mm_struct * mm = NULL; | ||
84 | |||
85 | if (task) { | ||
86 | mm = get_task_mm(task); | ||
87 | put_task_struct(task); | ||
88 | } | ||
89 | if (!mm) | ||
90 | goto out; | ||
91 | down_read(&mm->mmap_sem); | ||
92 | |||
93 | vma = mm->mmap; | ||
94 | while (vma) { | ||
95 | if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) | ||
96 | break; | ||
97 | vma = vma->vm_next; | ||
98 | } | ||
99 | |||
100 | if (vma) { | ||
101 | *path = vma->vm_file->f_path; | ||
102 | path_get(&vma->vm_file->f_path); | ||
103 | result = 0; | ||
104 | } | ||
105 | |||
106 | up_read(&mm->mmap_sem); | ||
107 | mmput(mm); | ||
108 | out: | ||
109 | return result; | ||
110 | } | ||
111 | |||
112 | static void pad_len_spaces(struct seq_file *m, int len) | 78 | static void pad_len_spaces(struct seq_file *m, int len) |
113 | { | 79 | { |
114 | len = 25 + sizeof(void*) * 6 - len; | 80 | len = 25 + sizeof(void*) * 6 - len; |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 8011528518bd..4b733f108455 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
@@ -103,40 +103,6 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, | |||
103 | return size; | 103 | return size; |
104 | } | 104 | } |
105 | 105 | ||
106 | int proc_exe_link(struct inode *inode, struct path *path) | ||
107 | { | ||
108 | struct vm_list_struct *vml; | ||
109 | struct vm_area_struct *vma; | ||
110 | struct task_struct *task = get_proc_task(inode); | ||
111 | struct mm_struct *mm = get_task_mm(task); | ||
112 | int result = -ENOENT; | ||
113 | |||
114 | if (!mm) | ||
115 | goto out; | ||
116 | down_read(&mm->mmap_sem); | ||
117 | |||
118 | vml = mm->context.vmlist; | ||
119 | vma = NULL; | ||
120 | while (vml) { | ||
121 | if ((vml->vma->vm_flags & VM_EXECUTABLE) && vml->vma->vm_file) { | ||
122 | vma = vml->vma; | ||
123 | break; | ||
124 | } | ||
125 | vml = vml->next; | ||
126 | } | ||
127 | |||
128 | if (vma) { | ||
129 | *path = vma->vm_file->f_path; | ||
130 | path_get(&vma->vm_file->f_path); | ||
131 | result = 0; | ||
132 | } | ||
133 | |||
134 | up_read(&mm->mmap_sem); | ||
135 | mmput(mm); | ||
136 | out: | ||
137 | return result; | ||
138 | } | ||
139 | |||
140 | /* | 106 | /* |
141 | * display mapping lines for a particular process's /proc/pid/maps | 107 | * display mapping lines for a particular process's /proc/pid/maps |
142 | */ | 108 | */ |
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c index b41a514b0976..9590b9024300 100644 --- a/fs/ramfs/file-mmu.c +++ b/fs/ramfs/file-mmu.c | |||
@@ -26,6 +26,9 @@ | |||
26 | 26 | ||
27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/ramfs.h> | ||
30 | |||
31 | #include "internal.h" | ||
29 | 32 | ||
30 | const struct address_space_operations ramfs_aops = { | 33 | const struct address_space_operations ramfs_aops = { |
31 | .readpage = simple_readpage, | 34 | .readpage = simple_readpage, |
diff --git a/fs/ramfs/internal.h b/fs/ramfs/internal.h index af7cc074a476..6b330639b51d 100644 --- a/fs/ramfs/internal.h +++ b/fs/ramfs/internal.h | |||
@@ -11,5 +11,4 @@ | |||
11 | 11 | ||
12 | 12 | ||
13 | extern const struct address_space_operations ramfs_aops; | 13 | extern const struct address_space_operations ramfs_aops; |
14 | extern const struct file_operations ramfs_file_operations; | ||
15 | extern const struct inode_operations ramfs_file_inode_operations; | 14 | extern const struct inode_operations ramfs_file_inode_operations; |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 8f86c52b30d8..b9dbeeca7049 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
@@ -467,6 +467,7 @@ static const struct file_operations r_file_operations = { | |||
467 | .read = seq_read, | 467 | .read = seq_read, |
468 | .llseek = seq_lseek, | 468 | .llseek = seq_lseek, |
469 | .release = seq_release, | 469 | .release = seq_release, |
470 | .owner = THIS_MODULE, | ||
470 | }; | 471 | }; |
471 | 472 | ||
472 | static struct proc_dir_entry *proc_info_root = NULL; | 473 | static struct proc_dir_entry *proc_info_root = NULL; |
@@ -475,12 +476,8 @@ static const char proc_info_root_name[] = "fs/reiserfs"; | |||
475 | static void add_file(struct super_block *sb, char *name, | 476 | static void add_file(struct super_block *sb, char *name, |
476 | int (*func) (struct seq_file *, struct super_block *)) | 477 | int (*func) (struct seq_file *, struct super_block *)) |
477 | { | 478 | { |
478 | struct proc_dir_entry *de; | 479 | proc_create_data(name, 0, REISERFS_SB(sb)->procdir, |
479 | de = create_proc_entry(name, 0, REISERFS_SB(sb)->procdir); | 480 | &r_file_operations, func); |
480 | if (de) { | ||
481 | de->data = func; | ||
482 | de->proc_fops = &r_file_operations; | ||
483 | } | ||
484 | } | 481 | } |
485 | 482 | ||
486 | int reiserfs_proc_info_init(struct super_block *sb) | 483 | int reiserfs_proc_info_init(struct super_block *sb) |
diff --git a/fs/super.c b/fs/super.c index a5a4aca7e22f..453877c5697b 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -117,7 +117,7 @@ static inline void destroy_super(struct super_block *s) | |||
117 | * Drop a superblock's refcount. Returns non-zero if the superblock was | 117 | * Drop a superblock's refcount. Returns non-zero if the superblock was |
118 | * destroyed. The caller must hold sb_lock. | 118 | * destroyed. The caller must hold sb_lock. |
119 | */ | 119 | */ |
120 | int __put_super(struct super_block *sb) | 120 | static int __put_super(struct super_block *sb) |
121 | { | 121 | { |
122 | int ret = 0; | 122 | int ret = 0; |
123 | 123 | ||
@@ -64,7 +64,7 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync) | |||
64 | /* sync the superblock to buffers */ | 64 | /* sync the superblock to buffers */ |
65 | sb = inode->i_sb; | 65 | sb = inode->i_sb; |
66 | lock_super(sb); | 66 | lock_super(sb); |
67 | if (sb->s_op->write_super) | 67 | if (sb->s_dirt && sb->s_op->write_super) |
68 | sb->s_op->write_super(sb); | 68 | sb->s_op->write_super(sb); |
69 | unlock_super(sb); | 69 | unlock_super(sb); |
70 | 70 | ||
diff --git a/fs/timerfd.c b/fs/timerfd.c index 10c80b59ec4b..5400524e9cb1 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/hrtimer.h> | 20 | #include <linux/hrtimer.h> |
21 | #include <linux/anon_inodes.h> | 21 | #include <linux/anon_inodes.h> |
22 | #include <linux/timerfd.h> | 22 | #include <linux/timerfd.h> |
23 | #include <linux/syscalls.h> | ||
23 | 24 | ||
24 | struct timerfd_ctx { | 25 | struct timerfd_ctx { |
25 | struct hrtimer tmr; | 26 | struct hrtimer tmr; |
diff --git a/fs/xattr.c b/fs/xattr.c index 89a942f07e1b..4706a8b1f495 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -67,7 +67,7 @@ xattr_permission(struct inode *inode, const char *name, int mask) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | int | 69 | int |
70 | vfs_setxattr(struct dentry *dentry, char *name, void *value, | 70 | vfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
71 | size_t size, int flags) | 71 | size_t size, int flags) |
72 | { | 72 | { |
73 | struct inode *inode = dentry->d_inode; | 73 | struct inode *inode = dentry->d_inode; |
@@ -131,7 +131,7 @@ out_noalloc: | |||
131 | EXPORT_SYMBOL_GPL(xattr_getsecurity); | 131 | EXPORT_SYMBOL_GPL(xattr_getsecurity); |
132 | 132 | ||
133 | ssize_t | 133 | ssize_t |
134 | vfs_getxattr(struct dentry *dentry, char *name, void *value, size_t size) | 134 | vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) |
135 | { | 135 | { |
136 | struct inode *inode = dentry->d_inode; | 136 | struct inode *inode = dentry->d_inode; |
137 | int error; | 137 | int error; |
@@ -187,7 +187,7 @@ vfs_listxattr(struct dentry *d, char *list, size_t size) | |||
187 | EXPORT_SYMBOL_GPL(vfs_listxattr); | 187 | EXPORT_SYMBOL_GPL(vfs_listxattr); |
188 | 188 | ||
189 | int | 189 | int |
190 | vfs_removexattr(struct dentry *dentry, char *name) | 190 | vfs_removexattr(struct dentry *dentry, const char *name) |
191 | { | 191 | { |
192 | struct inode *inode = dentry->d_inode; | 192 | struct inode *inode = dentry->d_inode; |
193 | int error; | 193 | int error; |
@@ -218,7 +218,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr); | |||
218 | * Extended attribute SET operations | 218 | * Extended attribute SET operations |
219 | */ | 219 | */ |
220 | static long | 220 | static long |
221 | setxattr(struct dentry *d, char __user *name, void __user *value, | 221 | setxattr(struct dentry *d, const char __user *name, const void __user *value, |
222 | size_t size, int flags) | 222 | size_t size, int flags) |
223 | { | 223 | { |
224 | int error; | 224 | int error; |
@@ -252,8 +252,8 @@ setxattr(struct dentry *d, char __user *name, void __user *value, | |||
252 | } | 252 | } |
253 | 253 | ||
254 | asmlinkage long | 254 | asmlinkage long |
255 | sys_setxattr(char __user *path, char __user *name, void __user *value, | 255 | sys_setxattr(const char __user *path, const char __user *name, |
256 | size_t size, int flags) | 256 | const void __user *value, size_t size, int flags) |
257 | { | 257 | { |
258 | struct nameidata nd; | 258 | struct nameidata nd; |
259 | int error; | 259 | int error; |
@@ -271,8 +271,8 @@ sys_setxattr(char __user *path, char __user *name, void __user *value, | |||
271 | } | 271 | } |
272 | 272 | ||
273 | asmlinkage long | 273 | asmlinkage long |
274 | sys_lsetxattr(char __user *path, char __user *name, void __user *value, | 274 | sys_lsetxattr(const char __user *path, const char __user *name, |
275 | size_t size, int flags) | 275 | const void __user *value, size_t size, int flags) |
276 | { | 276 | { |
277 | struct nameidata nd; | 277 | struct nameidata nd; |
278 | int error; | 278 | int error; |
@@ -290,7 +290,7 @@ sys_lsetxattr(char __user *path, char __user *name, void __user *value, | |||
290 | } | 290 | } |
291 | 291 | ||
292 | asmlinkage long | 292 | asmlinkage long |
293 | sys_fsetxattr(int fd, char __user *name, void __user *value, | 293 | sys_fsetxattr(int fd, const char __user *name, const void __user *value, |
294 | size_t size, int flags) | 294 | size_t size, int flags) |
295 | { | 295 | { |
296 | struct file *f; | 296 | struct file *f; |
@@ -315,7 +315,8 @@ sys_fsetxattr(int fd, char __user *name, void __user *value, | |||
315 | * Extended attribute GET operations | 315 | * Extended attribute GET operations |
316 | */ | 316 | */ |
317 | static ssize_t | 317 | static ssize_t |
318 | getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) | 318 | getxattr(struct dentry *d, const char __user *name, void __user *value, |
319 | size_t size) | ||
319 | { | 320 | { |
320 | ssize_t error; | 321 | ssize_t error; |
321 | void *kvalue = NULL; | 322 | void *kvalue = NULL; |
@@ -349,8 +350,8 @@ getxattr(struct dentry *d, char __user *name, void __user *value, size_t size) | |||
349 | } | 350 | } |
350 | 351 | ||
351 | asmlinkage ssize_t | 352 | asmlinkage ssize_t |
352 | sys_getxattr(char __user *path, char __user *name, void __user *value, | 353 | sys_getxattr(const char __user *path, const char __user *name, |
353 | size_t size) | 354 | void __user *value, size_t size) |
354 | { | 355 | { |
355 | struct nameidata nd; | 356 | struct nameidata nd; |
356 | ssize_t error; | 357 | ssize_t error; |
@@ -364,7 +365,7 @@ sys_getxattr(char __user *path, char __user *name, void __user *value, | |||
364 | } | 365 | } |
365 | 366 | ||
366 | asmlinkage ssize_t | 367 | asmlinkage ssize_t |
367 | sys_lgetxattr(char __user *path, char __user *name, void __user *value, | 368 | sys_lgetxattr(const char __user *path, const char __user *name, void __user *value, |
368 | size_t size) | 369 | size_t size) |
369 | { | 370 | { |
370 | struct nameidata nd; | 371 | struct nameidata nd; |
@@ -379,7 +380,7 @@ sys_lgetxattr(char __user *path, char __user *name, void __user *value, | |||
379 | } | 380 | } |
380 | 381 | ||
381 | asmlinkage ssize_t | 382 | asmlinkage ssize_t |
382 | sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size) | 383 | sys_fgetxattr(int fd, const char __user *name, void __user *value, size_t size) |
383 | { | 384 | { |
384 | struct file *f; | 385 | struct file *f; |
385 | ssize_t error = -EBADF; | 386 | ssize_t error = -EBADF; |
@@ -424,7 +425,7 @@ listxattr(struct dentry *d, char __user *list, size_t size) | |||
424 | } | 425 | } |
425 | 426 | ||
426 | asmlinkage ssize_t | 427 | asmlinkage ssize_t |
427 | sys_listxattr(char __user *path, char __user *list, size_t size) | 428 | sys_listxattr(const char __user *path, char __user *list, size_t size) |
428 | { | 429 | { |
429 | struct nameidata nd; | 430 | struct nameidata nd; |
430 | ssize_t error; | 431 | ssize_t error; |
@@ -438,7 +439,7 @@ sys_listxattr(char __user *path, char __user *list, size_t size) | |||
438 | } | 439 | } |
439 | 440 | ||
440 | asmlinkage ssize_t | 441 | asmlinkage ssize_t |
441 | sys_llistxattr(char __user *path, char __user *list, size_t size) | 442 | sys_llistxattr(const char __user *path, char __user *list, size_t size) |
442 | { | 443 | { |
443 | struct nameidata nd; | 444 | struct nameidata nd; |
444 | ssize_t error; | 445 | ssize_t error; |
@@ -470,7 +471,7 @@ sys_flistxattr(int fd, char __user *list, size_t size) | |||
470 | * Extended attribute REMOVE operations | 471 | * Extended attribute REMOVE operations |
471 | */ | 472 | */ |
472 | static long | 473 | static long |
473 | removexattr(struct dentry *d, char __user *name) | 474 | removexattr(struct dentry *d, const char __user *name) |
474 | { | 475 | { |
475 | int error; | 476 | int error; |
476 | char kname[XATTR_NAME_MAX + 1]; | 477 | char kname[XATTR_NAME_MAX + 1]; |
@@ -485,7 +486,7 @@ removexattr(struct dentry *d, char __user *name) | |||
485 | } | 486 | } |
486 | 487 | ||
487 | asmlinkage long | 488 | asmlinkage long |
488 | sys_removexattr(char __user *path, char __user *name) | 489 | sys_removexattr(const char __user *path, const char __user *name) |
489 | { | 490 | { |
490 | struct nameidata nd; | 491 | struct nameidata nd; |
491 | int error; | 492 | int error; |
@@ -503,7 +504,7 @@ sys_removexattr(char __user *path, char __user *name) | |||
503 | } | 504 | } |
504 | 505 | ||
505 | asmlinkage long | 506 | asmlinkage long |
506 | sys_lremovexattr(char __user *path, char __user *name) | 507 | sys_lremovexattr(const char __user *path, const char __user *name) |
507 | { | 508 | { |
508 | struct nameidata nd; | 509 | struct nameidata nd; |
509 | int error; | 510 | int error; |
@@ -521,7 +522,7 @@ sys_lremovexattr(char __user *path, char __user *name) | |||
521 | } | 522 | } |
522 | 523 | ||
523 | asmlinkage long | 524 | asmlinkage long |
524 | sys_fremovexattr(int fd, char __user *name) | 525 | sys_fremovexattr(int fd, const char __user *name) |
525 | { | 526 | { |
526 | struct file *f; | 527 | struct file *f; |
527 | struct dentry *dentry; | 528 | struct dentry *dentry; |