From: Greg Kroah-Hartman Date: Wed, 17 Oct 2012 21:54:28 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.0.47~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2c69f04e7a9f54f163375b2e6d00871e0d84e268;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch ecryptfs-call-lower-flush-from-ecryptfs_flush.patch ecryptfs-initialize-empty-lower-files-when-opening-them.patch ecryptfs-revert-to-a-writethrough-cache-model.patch ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch usb-gadget-at91_udc-fix-dt-support.patch --- diff --git a/queue-3.4/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch b/queue-3.4/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch new file mode 100644 index 00000000000..46ab082f29d --- /dev/null +++ b/queue-3.4/e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch @@ -0,0 +1,81 @@ +From 8edc0e624db3756783233e464879eb2e3b904c13 Mon Sep 17 00:00:00 2001 +From: Hiroaki SHIMODA +Date: Wed, 10 Oct 2012 15:34:20 +0000 +Subject: e1000e: Change wthresh to 1 to avoid possible Tx stalls + +From: Hiroaki SHIMODA + +commit 8edc0e624db3756783233e464879eb2e3b904c13 upstream. + +This patch originated from Hiroaki SHIMODA but has been modified +by Intel with some minor cleanups and additional commit log text. + +Denys Fedoryshchenko and others reported Tx stalls on e1000e with +BQL enabled. Issue was root caused to hardware delays. They were +introduced because some of the e1000e hardware with transmit +writeback bursting enabled, waits until the driver does an +explict flush OR there are WTHRESH descriptors to write back. + +Sometimes the delays in question were on the order of seconds, +causing visible lag for ssh sessions and unacceptable tx +completion latency, especially for BQL enabled kernels. + +To avoid possible Tx stalls, change WTHRESH back to 1. + +The current plan is to investigate a method for re-enabling +WTHRESH while not harming BQL, but those patches will be later +for net-next if they work. + +please enqueue for stable since v3.3 as this bug was introduced in +commit 3f0cfa3bc11e7f00c9994e0f469cbc0e7da7b00c +Author: Tom Herbert +Date: Mon Nov 28 16:33:16 2011 +0000 + + e1000e: Support for byte queue limits + + Changes to e1000e to use byte queue limits. + +Reported-by: Denys Fedoryshchenko +Tested-by: Denys Fedoryshchenko +Signed-off-by: Hiroaki SHIMODA +CC: eric.dumazet@gmail.com +CC: therbert@google.com +Signed-off-by: Jesse Brandeburg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/intel/e1000e/e1000.h | 6 +++--- + drivers/net/ethernet/intel/e1000e/netdev.c | 2 +- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/intel/e1000e/e1000.h ++++ b/drivers/net/ethernet/intel/e1000e/e1000.h +@@ -175,13 +175,13 @@ struct e1000_info; + /* + * in the case of WTHRESH, it appears at least the 82571/2 hardware + * writes back 4 descriptors when WTHRESH=5, and 3 descriptors when +- * WTHRESH=4, and since we want 64 bytes at a time written back, set +- * it to 5 ++ * WTHRESH=4, so a setting of 5 gives the most efficient bus ++ * utilization but to avoid possible Tx stalls, set it to 1 + */ + #define E1000_TXDCTL_DMA_BURST_ENABLE \ + (E1000_TXDCTL_GRAN | /* set descriptor granularity */ \ + E1000_TXDCTL_COUNT_DESC | \ +- (5 << 16) | /* wthresh must be +1 more than desired */\ ++ (1 << 16) | /* wthresh must be +1 more than desired */\ + (1 << 8) | /* hthresh */ \ + 0x1f) /* pthresh */ + +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -2806,7 +2806,7 @@ static void e1000_configure_tx(struct e1 + * set up some performance related parameters to encourage the + * hardware to use the bus more efficiently in bursts, depends + * on the tx_int_delay to be enabled, +- * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time ++ * wthresh = 1 ==> burst write is disabled to avoid Tx stalls + * hthresh = 1 ==> prefetch when one or more available + * pthresh = 0x1f ==> prefetch if internal cache 31 or less + * BEWARE: this seems to work but should be considered first if diff --git a/queue-3.4/ecryptfs-call-lower-flush-from-ecryptfs_flush.patch b/queue-3.4/ecryptfs-call-lower-flush-from-ecryptfs_flush.patch new file mode 100644 index 00000000000..e9488a5fd01 --- /dev/null +++ b/queue-3.4/ecryptfs-call-lower-flush-from-ecryptfs_flush.patch @@ -0,0 +1,45 @@ +From 64e6651dcc10e9d2cc6230208a8e6c2cfd19ae18 Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Wed, 12 Sep 2012 18:38:00 -0700 +Subject: eCryptfs: Call lower ->flush() from ecryptfs_flush() + +From: Tyler Hicks + +commit 64e6651dcc10e9d2cc6230208a8e6c2cfd19ae18 upstream. + +Since eCryptfs only calls fput() on the lower file in +ecryptfs_release(), eCryptfs should call the lower filesystem's +->flush() from ecryptfs_flush(). + +If the lower filesystem implements ->flush(), then eCryptfs should try +to flush out any dirty pages prior to calling the lower ->flush(). If +the lower filesystem does not implement ->flush(), then eCryptfs has no +need to do anything in ecryptfs_flush() since dirty pages are now +written out to the lower filesystem in ecryptfs_release(). + +Signed-off-by: Tyler Hicks +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/file.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/fs/ecryptfs/file.c ++++ b/fs/ecryptfs/file.c +@@ -275,8 +275,14 @@ out: + + static int ecryptfs_flush(struct file *file, fl_owner_t td) + { +- return file->f_mode & FMODE_WRITE +- ? filemap_write_and_wait(file->f_mapping) : 0; ++ struct file *lower_file = ecryptfs_file_to_lower(file); ++ ++ if (lower_file->f_op && lower_file->f_op->flush) { ++ filemap_write_and_wait(file->f_mapping); ++ return lower_file->f_op->flush(lower_file, td); ++ } ++ ++ return 0; + } + + static int ecryptfs_release(struct inode *inode, struct file *file) diff --git a/queue-3.4/ecryptfs-initialize-empty-lower-files-when-opening-them.patch b/queue-3.4/ecryptfs-initialize-empty-lower-files-when-opening-them.patch new file mode 100644 index 00000000000..3be490d6f55 --- /dev/null +++ b/queue-3.4/ecryptfs-initialize-empty-lower-files-when-opening-them.patch @@ -0,0 +1,157 @@ +From e3ccaa9761200952cc269b1f4b7d7bb77a5e071b Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Wed, 20 Jun 2012 23:50:59 -0700 +Subject: eCryptfs: Initialize empty lower files when opening them + +From: Tyler Hicks + +commit e3ccaa9761200952cc269b1f4b7d7bb77a5e071b upstream. + +Historically, eCryptfs has only initialized lower files in the +ecryptfs_create() path. Lower file initialization is the act of writing +the cryptographic metadata from the inode's crypt_stat to the header of +the file. The ecryptfs_open() path already expects that metadata to be +in the header of the file. + +A number of users have reported empty lower files in beneath their +eCryptfs mounts. Most of the causes for those empty files being left +around have been addressed, but the presence of empty files causes +problems due to the lack of proper cryptographic metadata. + +To transparently solve this problem, this patch initializes empty lower +files in the ecryptfs_open() error path. If the metadata is unreadable +due to the lower inode size being 0, plaintext passthrough support is +not in use, and the metadata is stored in the header of the file (as +opposed to the user.ecryptfs extended attribute), the lower file will be +initialized. + +The number of nested conditionals in ecryptfs_open() was getting out of +hand, so a helper function was created. To avoid the same nested +conditional problem, the conditional logic was reversed inside of the +helper function. + +https://launchpad.net/bugs/911507 + +Signed-off-by: Tyler Hicks +Cc: John Johansen +Cc: Colin Ian King +Cc: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/ecryptfs_kernel.h | 2 + + fs/ecryptfs/file.c | 71 ++++++++++++++++++++++++++---------------- + fs/ecryptfs/inode.c | 4 +- + 3 files changed, 49 insertions(+), 28 deletions(-) + +--- a/fs/ecryptfs/ecryptfs_kernel.h ++++ b/fs/ecryptfs/ecryptfs_kernel.h +@@ -568,6 +568,8 @@ struct ecryptfs_open_req { + struct inode *ecryptfs_get_inode(struct inode *lower_inode, + struct super_block *sb); + void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); ++int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, ++ struct inode *ecryptfs_inode); + int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, + size_t *decrypted_name_size, + struct dentry *ecryptfs_dentry, +--- a/fs/ecryptfs/file.c ++++ b/fs/ecryptfs/file.c +@@ -161,6 +161,48 @@ static int ecryptfs_file_mmap(struct fil + + struct kmem_cache *ecryptfs_file_info_cache; + ++static int read_or_initialize_metadata(struct dentry *dentry) ++{ ++ struct inode *inode = dentry->d_inode; ++ struct ecryptfs_mount_crypt_stat *mount_crypt_stat; ++ struct ecryptfs_crypt_stat *crypt_stat; ++ int rc; ++ ++ crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; ++ mount_crypt_stat = &ecryptfs_superblock_to_private( ++ inode->i_sb)->mount_crypt_stat; ++ mutex_lock(&crypt_stat->cs_mutex); ++ ++ if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED && ++ crypt_stat->flags & ECRYPTFS_KEY_VALID) { ++ rc = 0; ++ goto out; ++ } ++ ++ rc = ecryptfs_read_metadata(dentry); ++ if (!rc) ++ goto out; ++ ++ if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) { ++ crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED ++ | ECRYPTFS_ENCRYPTED); ++ rc = 0; ++ goto out; ++ } ++ ++ if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) && ++ !i_size_read(ecryptfs_inode_to_lower(inode))) { ++ rc = ecryptfs_initialize_file(dentry, inode); ++ if (!rc) ++ goto out; ++ } ++ ++ rc = -EIO; ++out: ++ mutex_unlock(&crypt_stat->cs_mutex); ++ return rc; ++} ++ + /** + * ecryptfs_open + * @inode: inode speciying file to open +@@ -236,32 +278,9 @@ static int ecryptfs_open(struct inode *i + rc = 0; + goto out; + } +- mutex_lock(&crypt_stat->cs_mutex); +- if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) +- || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { +- rc = ecryptfs_read_metadata(ecryptfs_dentry); +- if (rc) { +- ecryptfs_printk(KERN_DEBUG, +- "Valid headers not found\n"); +- if (!(mount_crypt_stat->flags +- & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { +- rc = -EIO; +- printk(KERN_WARNING "Either the lower file " +- "is not in a valid eCryptfs format, " +- "or the key could not be retrieved. " +- "Plaintext passthrough mode is not " +- "enabled; returning -EIO\n"); +- mutex_unlock(&crypt_stat->cs_mutex); +- goto out_put; +- } +- rc = 0; +- crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED +- | ECRYPTFS_ENCRYPTED); +- mutex_unlock(&crypt_stat->cs_mutex); +- goto out; +- } +- } +- mutex_unlock(&crypt_stat->cs_mutex); ++ rc = read_or_initialize_metadata(ecryptfs_dentry); ++ if (rc) ++ goto out_put; + ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " + "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, + (unsigned long long)i_size_read(inode)); +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -227,8 +227,8 @@ out: + * + * Returns zero on success + */ +-static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, +- struct inode *ecryptfs_inode) ++int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, ++ struct inode *ecryptfs_inode) + { + struct ecryptfs_crypt_stat *crypt_stat = + &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; diff --git a/queue-3.4/ecryptfs-revert-to-a-writethrough-cache-model.patch b/queue-3.4/ecryptfs-revert-to-a-writethrough-cache-model.patch new file mode 100644 index 00000000000..3697bd81a6b --- /dev/null +++ b/queue-3.4/ecryptfs-revert-to-a-writethrough-cache-model.patch @@ -0,0 +1,187 @@ +From 821f7494a77627fb1ab539591c57b22cdca702d6 Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Tue, 3 Jul 2012 16:50:57 -0700 +Subject: eCryptfs: Revert to a writethrough cache model + +From: Tyler Hicks + +commit 821f7494a77627fb1ab539591c57b22cdca702d6 upstream. + +A change was made about a year ago to get eCryptfs to better utilize its +page cache during writes. The idea was to do the page encryption +operations during page writeback, rather than doing them when initially +writing into the page cache, to reduce the number of page encryption +operations during sequential writes. This meant that the encrypted page +would only be written to the lower filesystem during page writeback, +which was a change from how eCryptfs had previously wrote to the lower +filesystem in ecryptfs_write_end(). + +The change caused a few eCryptfs-internal bugs that were shook out. +Unfortunately, more grave side effects have been identified that will +force changes outside of eCryptfs. Because the lower filesystem isn't +consulted until page writeback, eCryptfs has no way to pass lower write +errors (ENOSPC, mainly) back to userspace. Additionaly, it was reported +that quotas could be bypassed because of the way eCryptfs may sometimes +open the lower filesystem using a privileged kthread. + +It would be nice to resolve the latest issues, but it is best if the +eCryptfs commits be reverted to the old behavior in the meantime. + +This reverts: +32001d6f "eCryptfs: Flush file in vma close" +5be79de2 "eCryptfs: Flush dirty pages in setattr" +57db4e8d "ecryptfs: modify write path to encrypt page in writepage" + +Signed-off-by: Tyler Hicks +Tested-by: Colin King +Cc: Colin King +Cc: Thieu Le +Cc: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/file.c | 33 ++------------------------------- + fs/ecryptfs/inode.c | 6 ------ + fs/ecryptfs/mmap.c | 39 +++++++++++++-------------------------- + 3 files changed, 15 insertions(+), 63 deletions(-) + +--- a/fs/ecryptfs/file.c ++++ b/fs/ecryptfs/file.c +@@ -138,27 +138,6 @@ out: + return rc; + } + +-static void ecryptfs_vma_close(struct vm_area_struct *vma) +-{ +- filemap_write_and_wait(vma->vm_file->f_mapping); +-} +- +-static const struct vm_operations_struct ecryptfs_file_vm_ops = { +- .close = ecryptfs_vma_close, +- .fault = filemap_fault, +-}; +- +-static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma) +-{ +- int rc; +- +- rc = generic_file_mmap(file, vma); +- if (!rc) +- vma->vm_ops = &ecryptfs_file_vm_ops; +- +- return rc; +-} +- + struct kmem_cache *ecryptfs_file_info_cache; + + static int read_or_initialize_metadata(struct dentry *dentry) +@@ -311,15 +290,7 @@ static int ecryptfs_release(struct inode + static int + ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) + { +- int rc = 0; +- +- rc = generic_file_fsync(file, start, end, datasync); +- if (rc) +- goto out; +- rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end, +- datasync); +-out: +- return rc; ++ return vfs_fsync(ecryptfs_file_to_lower(file), datasync); + } + + static int ecryptfs_fasync(int fd, struct file *file, int flag) +@@ -388,7 +359,7 @@ const struct file_operations ecryptfs_ma + #ifdef CONFIG_COMPAT + .compat_ioctl = ecryptfs_compat_ioctl, + #endif +- .mmap = ecryptfs_file_mmap, ++ .mmap = generic_file_mmap, + .open = ecryptfs_open, + .flush = ecryptfs_flush, + .release = ecryptfs_release, +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -1016,12 +1016,6 @@ static int ecryptfs_setattr(struct dentr + goto out; + } + +- if (S_ISREG(inode->i_mode)) { +- rc = filemap_write_and_wait(inode->i_mapping); +- if (rc) +- goto out; +- fsstack_copy_attr_all(inode, lower_inode); +- } + memcpy(&lower_ia, ia, sizeof(lower_ia)); + if (ia->ia_valid & ATTR_FILE) + lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); +--- a/fs/ecryptfs/mmap.c ++++ b/fs/ecryptfs/mmap.c +@@ -66,18 +66,6 @@ static int ecryptfs_writepage(struct pag + { + int rc; + +- /* +- * Refuse to write the page out if we are called from reclaim context +- * since our writepage() path may potentially allocate memory when +- * calling into the lower fs vfs_write() which may in turn invoke +- * us again. +- */ +- if (current->flags & PF_MEMALLOC) { +- redirty_page_for_writepage(wbc, page); +- rc = 0; +- goto out; +- } +- + rc = ecryptfs_encrypt_page(page); + if (rc) { + ecryptfs_printk(KERN_WARNING, "Error encrypting " +@@ -498,7 +486,6 @@ static int ecryptfs_write_end(struct fil + struct ecryptfs_crypt_stat *crypt_stat = + &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; + int rc; +- int need_unlock_page = 1; + + ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" + "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); +@@ -519,26 +506,26 @@ static int ecryptfs_write_end(struct fil + "zeros in page with index = [0x%.16lx]\n", index); + goto out; + } +- set_page_dirty(page); +- unlock_page(page); +- need_unlock_page = 0; ++ rc = ecryptfs_encrypt_page(page); ++ if (rc) { ++ ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " ++ "index [0x%.16lx])\n", index); ++ goto out; ++ } + if (pos + copied > i_size_read(ecryptfs_inode)) { + i_size_write(ecryptfs_inode, pos + copied); + ecryptfs_printk(KERN_DEBUG, "Expanded file size to " + "[0x%.16llx]\n", + (unsigned long long)i_size_read(ecryptfs_inode)); +- balance_dirty_pages_ratelimited(mapping); +- rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); +- if (rc) { +- printk(KERN_ERR "Error writing inode size to metadata; " +- "rc = [%d]\n", rc); +- goto out; +- } + } +- rc = copied; ++ rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); ++ if (rc) ++ printk(KERN_ERR "Error writing inode size to metadata; " ++ "rc = [%d]\n", rc); ++ else ++ rc = copied; + out: +- if (need_unlock_page) +- unlock_page(page); ++ unlock_page(page); + page_cache_release(page); + return rc; + } diff --git a/queue-3.4/ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch b/queue-3.4/ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch new file mode 100644 index 00000000000..76169873c18 --- /dev/null +++ b/queue-3.4/ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch @@ -0,0 +1,120 @@ +From 8bc2d3cf612994a960c2e8eaea37f6676f67082a Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Tue, 22 May 2012 15:09:50 -0500 +Subject: eCryptfs: Unlink lower inode when ecryptfs_create() fails + +From: Tyler Hicks + +commit 8bc2d3cf612994a960c2e8eaea37f6676f67082a upstream. + +ecryptfs_create() creates a lower inode, allocates an eCryptfs inode, +initializes the eCryptfs inode and cryptographic metadata attached to +the inode, and then writes the metadata to the header of the file. + +If an error was to occur after the lower inode was created, an empty +lower file would be left in the lower filesystem. This is a problem +because ecryptfs_open() refuses to open any lower files which do not +have the appropriate metadata in the file header. + +This patch properly unlinks the lower inode when an error occurs in the +later stages of ecryptfs_create(), reducing the chance that an empty +lower file will be left in the lower filesystem. + +https://launchpad.net/bugs/872905 + +Signed-off-by: Tyler Hicks +Cc: John Johansen +Cc: Colin Ian King +Cc: Jonathan Nieder +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/inode.c | 55 ++++++++++++++++++++++++++++++---------------------- + 1 file changed, 32 insertions(+), 23 deletions(-) + +--- a/fs/ecryptfs/inode.c ++++ b/fs/ecryptfs/inode.c +@@ -143,6 +143,31 @@ static int ecryptfs_interpose(struct den + return 0; + } + ++static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, ++ struct inode *inode) ++{ ++ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); ++ struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); ++ struct dentry *lower_dir_dentry; ++ int rc; ++ ++ dget(lower_dentry); ++ lower_dir_dentry = lock_parent(lower_dentry); ++ rc = vfs_unlink(lower_dir_inode, lower_dentry); ++ if (rc) { ++ printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); ++ goto out_unlock; ++ } ++ fsstack_copy_attr_times(dir, lower_dir_inode); ++ set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); ++ inode->i_ctime = dir->i_ctime; ++ d_drop(dentry); ++out_unlock: ++ unlock_dir(lower_dir_dentry); ++ dput(lower_dentry); ++ return rc; ++} ++ + /** + * ecryptfs_do_create + * @directory_inode: inode of the new file's dentry's parent in ecryptfs +@@ -182,8 +207,10 @@ ecryptfs_do_create(struct inode *directo + } + inode = __ecryptfs_get_inode(lower_dentry->d_inode, + directory_inode->i_sb); +- if (IS_ERR(inode)) ++ if (IS_ERR(inode)) { ++ vfs_unlink(lower_dir_dentry->d_inode, lower_dentry); + goto out_lock; ++ } + fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); + fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); + out_lock: +@@ -265,7 +292,9 @@ ecryptfs_create(struct inode *directory_ + * that this on disk file is prepared to be an ecryptfs file */ + rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); + if (rc) { +- drop_nlink(ecryptfs_inode); ++ ecryptfs_do_unlink(directory_inode, ecryptfs_dentry, ++ ecryptfs_inode); ++ make_bad_inode(ecryptfs_inode); + unlock_new_inode(ecryptfs_inode); + iput(ecryptfs_inode); + goto out; +@@ -477,27 +506,7 @@ out_lock: + + static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) + { +- int rc = 0; +- struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); +- struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); +- struct dentry *lower_dir_dentry; +- +- dget(lower_dentry); +- lower_dir_dentry = lock_parent(lower_dentry); +- rc = vfs_unlink(lower_dir_inode, lower_dentry); +- if (rc) { +- printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); +- goto out_unlock; +- } +- fsstack_copy_attr_times(dir, lower_dir_inode); +- set_nlink(dentry->d_inode, +- ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink); +- dentry->d_inode->i_ctime = dir->i_ctime; +- d_drop(dentry); +-out_unlock: +- unlock_dir(lower_dir_dentry); +- dput(lower_dentry); +- return rc; ++ return ecryptfs_do_unlink(dir, dentry, dentry->d_inode); + } + + static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, diff --git a/queue-3.4/ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch b/queue-3.4/ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch new file mode 100644 index 00000000000..96dd71a3d1b --- /dev/null +++ b/queue-3.4/ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch @@ -0,0 +1,46 @@ +From 7149f2558d5b5b988726662fe58b1c388337805b Mon Sep 17 00:00:00 2001 +From: Tyler Hicks +Date: Wed, 12 Sep 2012 18:02:46 -0700 +Subject: eCryptfs: Write out all dirty pages just before releasing the lower file + +From: Tyler Hicks + +commit 7149f2558d5b5b988726662fe58b1c388337805b upstream. + +Fixes a regression caused by: + +821f749 eCryptfs: Revert to a writethrough cache model + +That patch reverted some code (specifically, 32001d6f) that was +necessary to properly handle open() -> mmap() -> close() -> dirty pages +-> munmap(), because the lower file could be closed before the dirty +pages are written out. + +Rather than reapplying 32001d6f, this approach is a better way of +ensuring that the lower file is still open in order to handle writing +out the dirty pages. It is called from ecryptfs_release(), while we have +a lock on the lower file pointer, just before the lower file gets the +final fput() and we overwrite the pointer. + +https://launchpad.net/bugs/1047261 + +Signed-off-by: Tyler Hicks +Reported-by: Artemy Tregubenko +Tested-by: Artemy Tregubenko +Tested-by: Colin Ian King +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ecryptfs/main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/ecryptfs/main.c ++++ b/fs/ecryptfs/main.c +@@ -162,6 +162,7 @@ void ecryptfs_put_lower_file(struct inod + inode_info = ecryptfs_inode_to_private(inode); + if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, + &inode_info->lower_file_mutex)) { ++ filemap_write_and_wait(inode->i_mapping); + fput(inode_info->lower_file); + inode_info->lower_file = NULL; + mutex_unlock(&inode_info->lower_file_mutex); diff --git a/queue-3.4/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch b/queue-3.4/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch new file mode 100644 index 00000000000..f28d028e4e1 --- /dev/null +++ b/queue-3.4/jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch @@ -0,0 +1,230 @@ +From 09e05d4805e6c524c1af74e524e5d0528bb3fef3 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 11 Jul 2012 23:16:25 +0200 +Subject: jbd: Fix assertion failure in commit code due to lacking transaction credits + +From: Jan Kara + +commit 09e05d4805e6c524c1af74e524e5d0528bb3fef3 upstream. + +ext3 users of data=journal mode with blocksize < pagesize were occasionally +hitting assertion failure in journal_commit_transaction() checking whether the +transaction has at least as many credits reserved as buffers attached. The +core of the problem is that when a file gets truncated, buffers that still need +checkpointing or that are attached to the committing transaction are left with +buffer_mapped set. When this happens to buffers beyond i_size attached to a +page stradding i_size, subsequent write extending the file will see these +buffers and as they are mapped (but underlying blocks were freed) things go +awry from here. + +The assertion failure just coincidentally (and in this case luckily as we would +start corrupting filesystem) triggers due to journal_head not being properly +cleaned up as well. + +Under some rare circumstances this bug could even hit data=ordered mode users. +There the assertion won't trigger and we would end up corrupting the +filesystem. + +We fix the problem by unmapping buffers if possible (in lots of cases we just +need a buffer attached to a transaction as a place holder but it must not be +written out anyway). And in one case, we just have to bite the bullet and wait +for transaction commit to finish. + +Reviewed-by: Josef Bacik +Signed-off-by: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jbd/commit.c | 45 +++++++++++++++++++++++++++-------- + fs/jbd/transaction.c | 64 +++++++++++++++++++++++++++++++++++---------------- + 2 files changed, 78 insertions(+), 31 deletions(-) + +--- a/fs/jbd/commit.c ++++ b/fs/jbd/commit.c +@@ -86,7 +86,12 @@ nope: + static void release_data_buffer(struct buffer_head *bh) + { + if (buffer_freed(bh)) { ++ WARN_ON_ONCE(buffer_dirty(bh)); + clear_buffer_freed(bh); ++ clear_buffer_mapped(bh); ++ clear_buffer_new(bh); ++ clear_buffer_req(bh); ++ bh->b_bdev = NULL; + release_buffer_page(bh); + } else + put_bh(bh); +@@ -853,17 +858,35 @@ restart_loop: + * there's no point in keeping a checkpoint record for + * it. */ + +- /* A buffer which has been freed while still being +- * journaled by a previous transaction may end up still +- * being dirty here, but we want to avoid writing back +- * that buffer in the future after the "add to orphan" +- * operation been committed, That's not only a performance +- * gain, it also stops aliasing problems if the buffer is +- * left behind for writeback and gets reallocated for another +- * use in a different page. */ +- if (buffer_freed(bh) && !jh->b_next_transaction) { +- clear_buffer_freed(bh); +- clear_buffer_jbddirty(bh); ++ /* ++ * A buffer which has been freed while still being journaled by ++ * a previous transaction. ++ */ ++ if (buffer_freed(bh)) { ++ /* ++ * If the running transaction is the one containing ++ * "add to orphan" operation (b_next_transaction != ++ * NULL), we have to wait for that transaction to ++ * commit before we can really get rid of the buffer. ++ * So just clear b_modified to not confuse transaction ++ * credit accounting and refile the buffer to ++ * BJ_Forget of the running transaction. If the just ++ * committed transaction contains "add to orphan" ++ * operation, we can completely invalidate the buffer ++ * now. We are rather throughout in that since the ++ * buffer may be still accessible when blocksize < ++ * pagesize and it is attached to the last partial ++ * page. ++ */ ++ jh->b_modified = 0; ++ if (!jh->b_next_transaction) { ++ clear_buffer_freed(bh); ++ clear_buffer_jbddirty(bh); ++ clear_buffer_mapped(bh); ++ clear_buffer_new(bh); ++ clear_buffer_req(bh); ++ bh->b_bdev = NULL; ++ } + } + + if (buffer_jbddirty(bh)) { +--- a/fs/jbd/transaction.c ++++ b/fs/jbd/transaction.c +@@ -1845,15 +1845,16 @@ static int __dispose_buffer(struct journ + * We're outside-transaction here. Either or both of j_running_transaction + * and j_committing_transaction may be NULL. + */ +-static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh) ++static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, ++ int partial_page) + { + transaction_t *transaction; + struct journal_head *jh; + int may_free = 1; +- int ret; + + BUFFER_TRACE(bh, "entry"); + ++retry: + /* + * It is safe to proceed here without the j_list_lock because the + * buffers cannot be stolen by try_to_free_buffers as long as we are +@@ -1881,10 +1882,18 @@ static int journal_unmap_buffer(journal_ + * clear the buffer dirty bit at latest at the moment when the + * transaction marking the buffer as freed in the filesystem + * structures is committed because from that moment on the +- * buffer can be reallocated and used by a different page. ++ * block can be reallocated and used by a different page. + * Since the block hasn't been freed yet but the inode has + * already been added to orphan list, it is safe for us to add + * the buffer to BJ_Forget list of the newest transaction. ++ * ++ * Also we have to clear buffer_mapped flag of a truncated buffer ++ * because the buffer_head may be attached to the page straddling ++ * i_size (can happen only when blocksize < pagesize) and thus the ++ * buffer_head can be reused when the file is extended again. So we end ++ * up keeping around invalidated buffers attached to transactions' ++ * BJ_Forget list just to stop checkpointing code from cleaning up ++ * the transaction this buffer was modified in. + */ + transaction = jh->b_transaction; + if (transaction == NULL) { +@@ -1911,13 +1920,9 @@ static int journal_unmap_buffer(journal_ + * committed, the buffer won't be needed any + * longer. */ + JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget"); +- ret = __dispose_buffer(jh, ++ may_free = __dispose_buffer(jh, + journal->j_running_transaction); +- journal_put_journal_head(jh); +- spin_unlock(&journal->j_list_lock); +- jbd_unlock_bh_state(bh); +- spin_unlock(&journal->j_state_lock); +- return ret; ++ goto zap_buffer; + } else { + /* There is no currently-running transaction. So the + * orphan record which we wrote for this file must have +@@ -1925,13 +1930,9 @@ static int journal_unmap_buffer(journal_ + * the committing transaction, if it exists. */ + if (journal->j_committing_transaction) { + JBUFFER_TRACE(jh, "give to committing trans"); +- ret = __dispose_buffer(jh, ++ may_free = __dispose_buffer(jh, + journal->j_committing_transaction); +- journal_put_journal_head(jh); +- spin_unlock(&journal->j_list_lock); +- jbd_unlock_bh_state(bh); +- spin_unlock(&journal->j_state_lock); +- return ret; ++ goto zap_buffer; + } else { + /* The orphan record's transaction has + * committed. We can cleanse this buffer */ +@@ -1952,10 +1953,24 @@ static int journal_unmap_buffer(journal_ + } + /* + * The buffer is committing, we simply cannot touch +- * it. So we just set j_next_transaction to the +- * running transaction (if there is one) and mark +- * buffer as freed so that commit code knows it should +- * clear dirty bits when it is done with the buffer. ++ * it. If the page is straddling i_size we have to wait ++ * for commit and try again. ++ */ ++ if (partial_page) { ++ tid_t tid = journal->j_committing_transaction->t_tid; ++ ++ journal_put_journal_head(jh); ++ spin_unlock(&journal->j_list_lock); ++ jbd_unlock_bh_state(bh); ++ spin_unlock(&journal->j_state_lock); ++ log_wait_commit(journal, tid); ++ goto retry; ++ } ++ /* ++ * OK, buffer won't be reachable after truncate. We just set ++ * j_next_transaction to the running transaction (if there is ++ * one) and mark buffer as freed so that commit code knows it ++ * should clear dirty bits when it is done with the buffer. + */ + set_buffer_freed(bh); + if (journal->j_running_transaction && buffer_jbddirty(bh)) +@@ -1978,6 +1993,14 @@ static int journal_unmap_buffer(journal_ + } + + zap_buffer: ++ /* ++ * This is tricky. Although the buffer is truncated, it may be reused ++ * if blocksize < pagesize and it is attached to the page straddling ++ * EOF. Since the buffer might have been added to BJ_Forget list of the ++ * running transaction, journal_get_write_access() won't clear ++ * b_modified and credit accounting gets confused. So clear b_modified ++ * here. */ ++ jh->b_modified = 0; + journal_put_journal_head(jh); + zap_buffer_no_jh: + spin_unlock(&journal->j_list_lock); +@@ -2026,7 +2049,8 @@ void journal_invalidatepage(journal_t *j + if (offset <= curr_off) { + /* This block is wholly outside the truncation point */ + lock_buffer(bh); +- may_free &= journal_unmap_buffer(journal, bh); ++ may_free &= journal_unmap_buffer(journal, bh, ++ offset > 0); + unlock_buffer(bh); + } + curr_off = next_off; diff --git a/queue-3.4/series b/queue-3.4/series index a4bfd644d73..1a6fa04be15 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -44,3 +44,12 @@ netfilter-xt_limit-have-r-cost-0-case-work.patch add-cdc-acm-support-for-the-cx93010-2x-ucmxx-usb-modem.patch drm-radeon-don-t-destroy-i2c-bus-rec-in-radeon_ext_tmds_enc_destroy.patch drm-i915-use-adjusted_mode-instead-of-mode-for-checking-the-6bpc-force-flag.patch +jbd-fix-assertion-failure-in-commit-code-due-to-lacking-transaction-credits.patch +e1000e-change-wthresh-to-1-to-avoid-possible-tx-stalls.patch +tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch +ecryptfs-unlink-lower-inode-when-ecryptfs_create-fails.patch +ecryptfs-initialize-empty-lower-files-when-opening-them.patch +ecryptfs-revert-to-a-writethrough-cache-model.patch +ecryptfs-write-out-all-dirty-pages-just-before-releasing-the-lower-file.patch +ecryptfs-call-lower-flush-from-ecryptfs_flush.patch +usb-gadget-at91_udc-fix-dt-support.patch diff --git a/queue-3.4/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch b/queue-3.4/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch new file mode 100644 index 00000000000..6d4e56b615d --- /dev/null +++ b/queue-3.4/tpm-propagate-error-from-tpm_transmit-to-fix-a-timeout-hang.patch @@ -0,0 +1,95 @@ +From abce9ac292e13da367bbd22c1f7669f988d931ac Mon Sep 17 00:00:00 2001 +From: Peter Huewe +Date: Thu, 27 Sep 2012 16:09:33 +0200 +Subject: tpm: Propagate error from tpm_transmit to fix a timeout hang + +From: Peter Huewe + +commit abce9ac292e13da367bbd22c1f7669f988d931ac upstream. + +tpm_write calls tpm_transmit without checking the return value and +assigns the return value unconditionally to chip->pending_data, even if +it's an error value. +This causes three bugs. + +So if we write to /dev/tpm0 with a tpm_param_size bigger than +TPM_BUFSIZE=0x1000 (e.g. 0x100a) +and a bufsize also bigger than TPM_BUFSIZE (e.g. 0x100a) +tpm_transmit returns -E2BIG which is assigned to chip->pending_data as +-7, but tpm_write returns that TPM_BUFSIZE bytes have been successfully +been written to the TPM, altough this is not true (bug #1). + +As we did write more than than TPM_BUFSIZE bytes but tpm_write reports +that only TPM_BUFSIZE bytes have been written the vfs tries to write +the remaining bytes (in this case 10 bytes) to the tpm device driver via +tpm_write which then blocks at + + /* cannot perform a write until the read has cleared + either via tpm_read or a user_read_timer timeout */ + while (atomic_read(&chip->data_pending) != 0) + msleep(TPM_TIMEOUT); + +for 60 seconds, since data_pending is -7 and nobody is able to +read it (since tpm_read luckily checks if data_pending is greater than +0) (#bug 2). + +After that the remaining bytes are written to the TPM which are +interpreted by the tpm as a normal command. (bug #3) +So if the last bytes of the command stream happen to be a e.g. +tpm_force_clear this gets accidentally sent to the TPM. + +This patch fixes all three bugs, by propagating the error code of +tpm_write and returning -E2BIG if the input buffer is too big, +since the response from the tpm for a truncated value is bogus anyway. +Moreover it returns -EBUSY to userspace if there is a response ready to be +read. + +Signed-off-by: Peter Huewe +Signed-off-by: Kent Yoder +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm.c | 21 ++++++++++++++------- + 1 file changed, 14 insertions(+), 7 deletions(-) + +--- a/drivers/char/tpm/tpm.c ++++ b/drivers/char/tpm/tpm.c +@@ -1186,17 +1186,20 @@ ssize_t tpm_write(struct file *file, con + size_t size, loff_t *off) + { + struct tpm_chip *chip = file->private_data; +- size_t in_size = size, out_size; ++ size_t in_size = size; ++ ssize_t out_size; + + /* cannot perform a write until the read has cleared +- either via tpm_read or a user_read_timer timeout */ +- while (atomic_read(&chip->data_pending) != 0) +- msleep(TPM_TIMEOUT); +- +- mutex_lock(&chip->buffer_mutex); ++ either via tpm_read or a user_read_timer timeout. ++ This also prevents splitted buffered writes from blocking here. ++ */ ++ if (atomic_read(&chip->data_pending) != 0) ++ return -EBUSY; + + if (in_size > TPM_BUFSIZE) +- in_size = TPM_BUFSIZE; ++ return -E2BIG; ++ ++ mutex_lock(&chip->buffer_mutex); + + if (copy_from_user + (chip->data_buffer, (void __user *) buf, in_size)) { +@@ -1206,6 +1209,10 @@ ssize_t tpm_write(struct file *file, con + + /* atomic tpm command send and result receive */ + out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); ++ if (out_size < 0) { ++ mutex_unlock(&chip->buffer_mutex); ++ return out_size; ++ } + + atomic_set(&chip->data_pending, out_size); + mutex_unlock(&chip->buffer_mutex); diff --git a/queue-3.4/usb-gadget-at91_udc-fix-dt-support.patch b/queue-3.4/usb-gadget-at91_udc-fix-dt-support.patch new file mode 100644 index 00000000000..414946d9b0e --- /dev/null +++ b/queue-3.4/usb-gadget-at91_udc-fix-dt-support.patch @@ -0,0 +1,31 @@ +From 9c6d196d5aa35e07482f23c3e37755e7a82140e0 Mon Sep 17 00:00:00 2001 +From: Fabio Porcedda +Date: Fri, 7 Sep 2012 15:27:42 +0200 +Subject: usb: gadget: at91_udc: fix dt support + +From: Fabio Porcedda + +commit 9c6d196d5aa35e07482f23c3e37755e7a82140e0 upstream. + +Don't fail the initialization check for the platform_data +if there is avaiable an associated device tree node. + +Signed-off-by: Fabio Porcedda +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/gadget/at91_udc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/gadget/at91_udc.c ++++ b/drivers/usb/gadget/at91_udc.c +@@ -1735,7 +1735,7 @@ static int __devinit at91udc_probe(struc + int retval; + struct resource *res; + +- if (!dev->platform_data) { ++ if (!dev->platform_data && !pdev->dev.of_node) { + /* small (so we copy it) but critical! */ + DBG("missing platform_data\n"); + return -ENODEV;