diff options
author | David Woodhouse <dwmw2@infradead.org> | 2007-07-04 20:24:57 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2007-07-04 20:24:57 -0400 |
commit | 9c5ef0fbfa0b0be219290b05a39135b957479251 (patch) | |
tree | deacd1ff7238ed0faf6a5d90f816e3135774b63d /fs | |
parent | 8f1a866fc6831f13593fae6194e3150d45976628 (diff) | |
parent | 190045d53b9a8341e8600d6eb468b6081e903afb (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs')
-rw-r--r-- | fs/direct-io.c | 2 | ||||
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 2 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 66 | ||||
-rw-r--r-- | fs/ecryptfs/mmap.c | 55 | ||||
-rw-r--r-- | fs/ext2/super.c | 1 | ||||
-rw-r--r-- | fs/signalfd.c | 3 | ||||
-rw-r--r-- | fs/sync.c | 8 |
7 files changed, 110 insertions, 27 deletions
diff --git a/fs/direct-io.c b/fs/direct-io.c index 8593f3dfd299..52bb2638f7ab 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -1106,7 +1106,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, | |||
1106 | spin_lock_irqsave(&dio->bio_lock, flags); | 1106 | spin_lock_irqsave(&dio->bio_lock, flags); |
1107 | ret2 = --dio->refcount; | 1107 | ret2 = --dio->refcount; |
1108 | spin_unlock_irqrestore(&dio->bio_lock, flags); | 1108 | spin_unlock_irqrestore(&dio->bio_lock, flags); |
1109 | BUG_ON(!dio->is_async && ret2 != 0); | 1109 | |
1110 | if (ret2 == 0) { | 1110 | if (ret2 == 0) { |
1111 | ret = dio_complete(dio, offset, ret); | 1111 | ret = dio_complete(dio, offset, ret); |
1112 | kfree(dio); | 1112 | kfree(dio); |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 403e3bad1455..1b9dd9a96f19 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -580,5 +580,7 @@ void | |||
580 | ecryptfs_write_header_metadata(char *virt, | 580 | ecryptfs_write_header_metadata(char *virt, |
581 | struct ecryptfs_crypt_stat *crypt_stat, | 581 | struct ecryptfs_crypt_stat *crypt_stat, |
582 | size_t *written); | 582 | size_t *written); |
583 | int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, | ||
584 | int num_zeros); | ||
583 | 585 | ||
584 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 586 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 1548be26b5e6..83e94fedd4e9 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -800,6 +800,25 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length) | |||
800 | goto out_fput; | 800 | goto out_fput; |
801 | } | 801 | } |
802 | } else { /* new_length < i_size_read(inode) */ | 802 | } else { /* new_length < i_size_read(inode) */ |
803 | pgoff_t index = 0; | ||
804 | int end_pos_in_page = -1; | ||
805 | |||
806 | if (new_length != 0) { | ||
807 | index = ((new_length - 1) >> PAGE_CACHE_SHIFT); | ||
808 | end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK); | ||
809 | } | ||
810 | if (end_pos_in_page != (PAGE_CACHE_SIZE - 1)) { | ||
811 | if ((rc = ecryptfs_write_zeros(&fake_ecryptfs_file, | ||
812 | index, | ||
813 | (end_pos_in_page + 1), | ||
814 | ((PAGE_CACHE_SIZE - 1) | ||
815 | - end_pos_in_page)))) { | ||
816 | printk(KERN_ERR "Error attempting to zero out " | ||
817 | "the remainder of the end page on " | ||
818 | "reducing truncate; rc = [%d]\n", rc); | ||
819 | goto out_fput; | ||
820 | } | ||
821 | } | ||
803 | vmtruncate(inode, new_length); | 822 | vmtruncate(inode, new_length); |
804 | rc = ecryptfs_write_inode_size_to_metadata( | 823 | rc = ecryptfs_write_inode_size_to_metadata( |
805 | lower_file, lower_dentry->d_inode, inode, dentry, | 824 | lower_file, lower_dentry->d_inode, inode, dentry, |
@@ -875,9 +894,54 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
875 | struct ecryptfs_crypt_stat *crypt_stat; | 894 | struct ecryptfs_crypt_stat *crypt_stat; |
876 | 895 | ||
877 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 896 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
878 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 897 | if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) |
898 | ecryptfs_init_crypt_stat(crypt_stat); | ||
879 | inode = dentry->d_inode; | 899 | inode = dentry->d_inode; |
880 | lower_inode = ecryptfs_inode_to_lower(inode); | 900 | lower_inode = ecryptfs_inode_to_lower(inode); |
901 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
902 | mutex_lock(&crypt_stat->cs_mutex); | ||
903 | if (S_ISDIR(dentry->d_inode->i_mode)) | ||
904 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
905 | else if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) | ||
906 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { | ||
907 | struct vfsmount *lower_mnt; | ||
908 | struct file *lower_file = NULL; | ||
909 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
910 | int lower_flags; | ||
911 | |||
912 | lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | ||
913 | lower_flags = O_RDONLY; | ||
914 | if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, | ||
915 | lower_mnt, lower_flags))) { | ||
916 | printk(KERN_ERR | ||
917 | "Error opening lower file; rc = [%d]\n", rc); | ||
918 | mutex_unlock(&crypt_stat->cs_mutex); | ||
919 | goto out; | ||
920 | } | ||
921 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
922 | dentry->d_sb)->mount_crypt_stat; | ||
923 | if ((rc = ecryptfs_read_metadata(dentry, lower_file))) { | ||
924 | if (!(mount_crypt_stat->flags | ||
925 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
926 | rc = -EIO; | ||
927 | printk(KERN_WARNING "Attempt to read file that " | ||
928 | "is not in a valid eCryptfs format, " | ||
929 | "and plaintext passthrough mode is not " | ||
930 | "enabled; returning -EIO\n"); | ||
931 | |||
932 | mutex_unlock(&crypt_stat->cs_mutex); | ||
933 | fput(lower_file); | ||
934 | goto out; | ||
935 | } | ||
936 | rc = 0; | ||
937 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | ||
938 | mutex_unlock(&crypt_stat->cs_mutex); | ||
939 | fput(lower_file); | ||
940 | goto out; | ||
941 | } | ||
942 | fput(lower_file); | ||
943 | } | ||
944 | mutex_unlock(&crypt_stat->cs_mutex); | ||
881 | if (ia->ia_valid & ATTR_SIZE) { | 945 | if (ia->ia_valid & ATTR_SIZE) { |
882 | ecryptfs_printk(KERN_DEBUG, | 946 | ecryptfs_printk(KERN_DEBUG, |
883 | "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", | 947 | "ia->ia_valid = [0x%x] ATTR_SIZE" " = [0x%x]\n", |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 55cec98a84e7..7d5a43cb0d5c 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -56,9 +56,6 @@ static struct page *ecryptfs_get1page(struct file *file, int index) | |||
56 | return read_mapping_page(mapping, index, (void *)file); | 56 | return read_mapping_page(mapping, index, (void *)file); |
57 | } | 57 | } |
58 | 58 | ||
59 | static | ||
60 | int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros); | ||
61 | |||
62 | /** | 59 | /** |
63 | * ecryptfs_fill_zeros | 60 | * ecryptfs_fill_zeros |
64 | * @file: The ecryptfs file | 61 | * @file: The ecryptfs file |
@@ -101,10 +98,13 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | |||
101 | if (old_end_page_index == new_end_page_index) { | 98 | if (old_end_page_index == new_end_page_index) { |
102 | /* Start and end are in the same page; we just need to | 99 | /* Start and end are in the same page; we just need to |
103 | * set a portion of the existing page to zero's */ | 100 | * set a portion of the existing page to zero's */ |
104 | rc = write_zeros(file, index, (old_end_pos_in_page + 1), | 101 | rc = ecryptfs_write_zeros(file, index, |
105 | (new_end_pos_in_page - old_end_pos_in_page)); | 102 | (old_end_pos_in_page + 1), |
103 | (new_end_pos_in_page | ||
104 | - old_end_pos_in_page)); | ||
106 | if (rc) | 105 | if (rc) |
107 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | 106 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(" |
107 | "file=[%p], " | ||
108 | "index=[0x%.16x], " | 108 | "index=[0x%.16x], " |
109 | "old_end_pos_in_page=[d], " | 109 | "old_end_pos_in_page=[d], " |
110 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" | 110 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" |
@@ -117,10 +117,10 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | |||
117 | goto out; | 117 | goto out; |
118 | } | 118 | } |
119 | /* Fill the remainder of the previous last page with zeros */ | 119 | /* Fill the remainder of the previous last page with zeros */ |
120 | rc = write_zeros(file, index, (old_end_pos_in_page + 1), | 120 | rc = ecryptfs_write_zeros(file, index, (old_end_pos_in_page + 1), |
121 | ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page)); | 121 | ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page)); |
122 | if (rc) { | 122 | if (rc) { |
123 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | 123 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=[%p], " |
124 | "index=[0x%.16x], old_end_pos_in_page=[d], " | 124 | "index=[0x%.16x], old_end_pos_in_page=[d], " |
125 | "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) " | 125 | "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) " |
126 | "returned [%d]\n", file, index, | 126 | "returned [%d]\n", file, index, |
@@ -131,9 +131,10 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | |||
131 | index++; | 131 | index++; |
132 | while (index < new_end_page_index) { | 132 | while (index < new_end_page_index) { |
133 | /* Fill all intermediate pages with zeros */ | 133 | /* Fill all intermediate pages with zeros */ |
134 | rc = write_zeros(file, index, 0, PAGE_CACHE_SIZE); | 134 | rc = ecryptfs_write_zeros(file, index, 0, PAGE_CACHE_SIZE); |
135 | if (rc) { | 135 | if (rc) { |
136 | ecryptfs_printk(KERN_ERR, "write_zeros(file=[%p], " | 136 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(" |
137 | "file=[%p], " | ||
137 | "index=[0x%.16x], " | 138 | "index=[0x%.16x], " |
138 | "old_end_pos_in_page=[d], " | 139 | "old_end_pos_in_page=[d], " |
139 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" | 140 | "(PAGE_CACHE_SIZE - new_end_pos_in_page" |
@@ -149,9 +150,9 @@ int ecryptfs_fill_zeros(struct file *file, loff_t new_length) | |||
149 | } | 150 | } |
150 | /* Fill the portion at the beginning of the last new page with | 151 | /* Fill the portion at the beginning of the last new page with |
151 | * zero's */ | 152 | * zero's */ |
152 | rc = write_zeros(file, index, 0, (new_end_pos_in_page + 1)); | 153 | rc = ecryptfs_write_zeros(file, index, 0, (new_end_pos_in_page + 1)); |
153 | if (rc) { | 154 | if (rc) { |
154 | ecryptfs_printk(KERN_ERR, "write_zeros(file=" | 155 | ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=" |
155 | "[%p], index=[0x%.16x], 0, " | 156 | "[%p], index=[0x%.16x], 0, " |
156 | "new_end_pos_in_page=[%d]" | 157 | "new_end_pos_in_page=[%d]" |
157 | "returned [%d]\n", file, index, | 158 | "returned [%d]\n", file, index, |
@@ -400,7 +401,6 @@ out: | |||
400 | static int ecryptfs_prepare_write(struct file *file, struct page *page, | 401 | static int ecryptfs_prepare_write(struct file *file, struct page *page, |
401 | unsigned from, unsigned to) | 402 | unsigned from, unsigned to) |
402 | { | 403 | { |
403 | loff_t pos; | ||
404 | int rc = 0; | 404 | int rc = 0; |
405 | 405 | ||
406 | if (from == 0 && to == PAGE_CACHE_SIZE) | 406 | if (from == 0 && to == PAGE_CACHE_SIZE) |
@@ -408,15 +408,22 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
408 | up to date. */ | 408 | up to date. */ |
409 | if (!PageUptodate(page)) | 409 | if (!PageUptodate(page)) |
410 | rc = ecryptfs_do_readpage(file, page, page->index); | 410 | rc = ecryptfs_do_readpage(file, page, page->index); |
411 | pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; | 411 | if (page->index != 0) { |
412 | if (pos > i_size_read(page->mapping->host)) { | 412 | loff_t end_of_prev_pg_pos = |
413 | rc = ecryptfs_truncate(file->f_path.dentry, pos); | 413 | (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); |
414 | if (rc) { | 414 | |
415 | printk(KERN_ERR "Error on attempt to " | 415 | if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { |
416 | "truncate to (higher) offset [%lld];" | 416 | rc = ecryptfs_truncate(file->f_path.dentry, |
417 | " rc = [%d]\n", pos, rc); | 417 | end_of_prev_pg_pos); |
418 | goto out; | 418 | if (rc) { |
419 | printk(KERN_ERR "Error on attempt to " | ||
420 | "truncate to (higher) offset [%lld];" | ||
421 | " rc = [%d]\n", end_of_prev_pg_pos, rc); | ||
422 | goto out; | ||
423 | } | ||
419 | } | 424 | } |
425 | if (end_of_prev_pg_pos + 1 > i_size_read(page->mapping->host)) | ||
426 | zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); | ||
420 | } | 427 | } |
421 | out: | 428 | out: |
422 | return rc; | 429 | return rc; |
@@ -753,7 +760,7 @@ out: | |||
753 | } | 760 | } |
754 | 761 | ||
755 | /** | 762 | /** |
756 | * write_zeros | 763 | * ecryptfs_write_zeros |
757 | * @file: The ecryptfs file | 764 | * @file: The ecryptfs file |
758 | * @index: The index in which we are writing | 765 | * @index: The index in which we are writing |
759 | * @start: The position after the last block of data | 766 | * @start: The position after the last block of data |
@@ -763,8 +770,8 @@ out: | |||
763 | * | 770 | * |
764 | * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE | 771 | * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE |
765 | */ | 772 | */ |
766 | static | 773 | int |
767 | int write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) | 774 | ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, int num_zeros) |
768 | { | 775 | { |
769 | int rc = 0; | 776 | int rc = 0; |
770 | struct page *tmp_page; | 777 | struct page *tmp_page; |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index c9fd8cf6eaa9..5de5061eb331 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -1043,6 +1043,7 @@ static int ext2_remount (struct super_block * sb, int * flags, char * data) | |||
1043 | 1043 | ||
1044 | if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) { | 1044 | if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) { |
1045 | printk("XIP: Unsupported blocksize\n"); | 1045 | printk("XIP: Unsupported blocksize\n"); |
1046 | err = -EINVAL; | ||
1046 | goto restore_opts; | 1047 | goto restore_opts; |
1047 | } | 1048 | } |
1048 | 1049 | ||
diff --git a/fs/signalfd.c b/fs/signalfd.c index f1da89203a9a..3b07f26d984d 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -133,7 +133,8 @@ static unsigned int signalfd_poll(struct file *file, poll_table *wait) | |||
133 | * the peer disconnects. | 133 | * the peer disconnects. |
134 | */ | 134 | */ |
135 | if (signalfd_lock(ctx, &lk)) { | 135 | if (signalfd_lock(ctx, &lk)) { |
136 | if (next_signal(&lk.tsk->pending, &ctx->sigmask) > 0 || | 136 | if ((lk.tsk == current && |
137 | next_signal(&lk.tsk->pending, &ctx->sigmask) > 0) || | ||
137 | next_signal(&lk.tsk->signal->shared_pending, | 138 | next_signal(&lk.tsk->signal->shared_pending, |
138 | &ctx->sigmask) > 0) | 139 | &ctx->sigmask) > 0) |
139 | events |= POLLIN; | 140 | events |= POLLIN; |
@@ -236,6 +236,14 @@ out: | |||
236 | return ret; | 236 | return ret; |
237 | } | 237 | } |
238 | 238 | ||
239 | /* It would be nice if people remember that not all the world's an i386 | ||
240 | when they introduce new system calls */ | ||
241 | asmlinkage long sys_sync_file_range2(int fd, unsigned int flags, | ||
242 | loff_t offset, loff_t nbytes) | ||
243 | { | ||
244 | return sys_sync_file_range(fd, offset, nbytes, flags); | ||
245 | } | ||
246 | |||
239 | /* | 247 | /* |
240 | * `endbyte' is inclusive | 248 | * `endbyte' is inclusive |
241 | */ | 249 | */ |