block: use an on-stack bio in blkdev_issue_flush
[linux-2.6-block.git] / fs / libfs.c
index 7124c2e8df2f5a5f49451ef8d3bb84c7b8712e80..8398a0efb401c659e9e919bdd3a46630d2cd30bd 100644 (file)
@@ -1117,7 +1117,7 @@ int generic_file_fsync(struct file *file, loff_t start, loff_t end,
        err = __generic_file_fsync(file, start, end, datasync);
        if (err)
                return err;
-       return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL);
+       return blkdev_issue_flush(inode->i_sb->s_bdev);
 }
 EXPORT_SYMBOL(generic_file_fsync);
 
@@ -1451,4 +1451,74 @@ int generic_ci_d_hash(const struct dentry *dentry, struct qstr *str)
        return 0;
 }
 EXPORT_SYMBOL(generic_ci_d_hash);
+
+static const struct dentry_operations generic_ci_dentry_ops = {
+       .d_hash = generic_ci_d_hash,
+       .d_compare = generic_ci_d_compare,
+};
+#endif
+
+#ifdef CONFIG_FS_ENCRYPTION
+static const struct dentry_operations generic_encrypted_dentry_ops = {
+       .d_revalidate = fscrypt_d_revalidate,
+};
+#endif
+
+#if defined(CONFIG_FS_ENCRYPTION) && defined(CONFIG_UNICODE)
+static const struct dentry_operations generic_encrypted_ci_dentry_ops = {
+       .d_hash = generic_ci_d_hash,
+       .d_compare = generic_ci_d_compare,
+       .d_revalidate = fscrypt_d_revalidate,
+};
+#endif
+
+/**
+ * generic_set_encrypted_ci_d_ops - helper for setting d_ops for given dentry
+ * @dentry:    dentry to set ops on
+ *
+ * Casefolded directories need d_hash and d_compare set, so that the dentries
+ * contained in them are handled case-insensitively.  Note that these operations
+ * are needed on the parent directory rather than on the dentries in it, and
+ * while the casefolding flag can be toggled on and off on an empty directory,
+ * dentry_operations can't be changed later.  As a result, if the filesystem has
+ * casefolding support enabled at all, we have to give all dentries the
+ * casefolding operations even if their inode doesn't have the casefolding flag
+ * currently (and thus the casefolding ops would be no-ops for now).
+ *
+ * Encryption works differently in that the only dentry operation it needs is
+ * d_revalidate, which it only needs on dentries that have the no-key name flag.
+ * The no-key flag can't be set "later", so we don't have to worry about that.
+ *
+ * Finally, to maximize compatibility with overlayfs (which isn't compatible
+ * with certain dentry operations) and to avoid taking an unnecessary
+ * performance hit, we use custom dentry_operations for each possible
+ * combination rather than always installing all operations.
+ */
+void generic_set_encrypted_ci_d_ops(struct dentry *dentry)
+{
+#ifdef CONFIG_FS_ENCRYPTION
+       bool needs_encrypt_ops = dentry->d_flags & DCACHE_NOKEY_NAME;
+#endif
+#ifdef CONFIG_UNICODE
+       bool needs_ci_ops = dentry->d_sb->s_encoding;
+#endif
+#if defined(CONFIG_FS_ENCRYPTION) && defined(CONFIG_UNICODE)
+       if (needs_encrypt_ops && needs_ci_ops) {
+               d_set_d_op(dentry, &generic_encrypted_ci_dentry_ops);
+               return;
+       }
 #endif
+#ifdef CONFIG_FS_ENCRYPTION
+       if (needs_encrypt_ops) {
+               d_set_d_op(dentry, &generic_encrypted_dentry_ops);
+               return;
+       }
+#endif
+#ifdef CONFIG_UNICODE
+       if (needs_ci_ops) {
+               d_set_d_op(dentry, &generic_ci_dentry_ops);
+               return;
+       }
+#endif
+}
+EXPORT_SYMBOL(generic_set_encrypted_ci_d_ops);