the ext4 encryption patches, which is a new feature added in the last
 merge window.  Also fix a number of long-standing xfstest failures.
 (Quota writes failing due to ENOSPC, a race between truncate and
 writepage in data=journalled mode that was causing generic/068 to
 fail, and other corner cases.)
 
 Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2
 performance eliminating locking when a buffer is modified more than
 once during a transaction (which is very common for allocation
 bitmaps, for example), in which case the state of the journalled
 buffer head doesn't need to change.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQEcBAABCAAGBQJVi3PeAAoJEPL5WVaVDYGj+I0H/jRPexvyvnGfxiqs1sxIlbSk
 cwewFJSsuKsy/pGYdmHvozWZyWGGORc89NrxoNwdbG+axvHbgUWt/3+vF+rzmaek
 vX4v9QvCEo4PfpRgzbnYJFhbxGMJtwci887sq1o/UoNXikFYT2kz8rpdf0++eO5W
 /GJNRA5ZUY0L0eeloUILAMrBr7KjtkI2oXwOZt5q68jh7B3n3XdNQXyEiQS/28aK
 QYcFrqA/e2Fiuk6l5OSGBCP38mySu+x0nBTLT5LFwwrUBnoZvGtdjM6Sj/yADDDn
 uP/Zpq56aLzkFRwwItrDaF26BIf2MhIH/WUYs65CraEGxjMaiPuzAudGA/iUVL8=
 =1BdR
 -----END PGP SIGNATURE-----
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o:
 "A very large number of cleanups and bug fixes --- in particular for
  the ext4 encryption patches, which is a new feature added in the last
  merge window.  Also fix a number of long-standing xfstest failures.
  (Quota writes failing due to ENOSPC, a race between truncate and
  writepage in data=journalled mode that was causing generic/068 to
  fail, and other corner cases.)
  Also add support for FALLOC_FL_INSERT_RANGE, and improve jbd2
  performance eliminating locking when a buffer is modified more than
  once during a transaction (which is very common for allocation
  bitmaps, for example), in which case the state of the journalled
  buffer head doesn't need to change"
[ I renamed "ext4_follow_link()" to "ext4_encrypted_follow_link()" in
  the merge resolution, to make it clear that that function is _only_
  used for encrypted symlinks.  The function doesn't actually work for
  non-encrypted symlinks at all, and they use the generic helpers
                                         - Linus ]
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (52 commits)
  ext4: set lazytime on remount if MS_LAZYTIME is set by mount
  ext4: only call ext4_truncate when size <= isize
  ext4: make online defrag error reporting consistent
  ext4: minor cleanup of ext4_da_reserve_space()
  ext4: don't retry file block mapping on bigalloc fs with non-extent file
  ext4: prevent ext4_quota_write() from failing due to ENOSPC
  ext4: call sync_blockdev() before invalidate_bdev() in put_super()
  jbd2: speedup jbd2_journal_dirty_metadata()
  jbd2: get rid of open coded allocation retry loop
  ext4: improve warning directory handling messages
  jbd2: fix ocfs2 corrupt when updating journal superblock fails
  ext4: mballoc: avoid 20-argument function call
  ext4: wait for existing dio workers in ext4_alloc_file_blocks()
  ext4: recalculate journal credits as inode depth changes
  jbd2: use GFP_NOFS in jbd2_cleanup_journal_tail()
  ext4: use swap() in mext_page_double_lock()
  ext4: use swap() in memswap()
  ext4: fix race between truncate and __ext4_journalled_writepage()
  ext4 crypto: fail the mount if blocksize != pagesize
  ext4: Add support FALLOC_FL_INSERT_RANGE for fallocate
  ...
		
	
			
		
			
				
	
	
		
			123 lines
		
	
	
	
		
			3.1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
	
		
			3.1 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  linux/fs/ext4/symlink.c
 | |
|  *
 | |
|  * Only fast symlinks left here - the rest is done by generic code. AV, 1999
 | |
|  *
 | |
|  * Copyright (C) 1992, 1993, 1994, 1995
 | |
|  * Remy Card (card@masi.ibp.fr)
 | |
|  * Laboratoire MASI - Institut Blaise Pascal
 | |
|  * Universite Pierre et Marie Curie (Paris VI)
 | |
|  *
 | |
|  *  from
 | |
|  *
 | |
|  *  linux/fs/minix/symlink.c
 | |
|  *
 | |
|  *  Copyright (C) 1991, 1992  Linus Torvalds
 | |
|  *
 | |
|  *  ext4 symlink handling code
 | |
|  */
 | |
| 
 | |
| #include <linux/fs.h>
 | |
| #include <linux/namei.h>
 | |
| #include "ext4.h"
 | |
| #include "xattr.h"
 | |
| 
 | |
| #ifdef CONFIG_EXT4_FS_ENCRYPTION
 | |
| static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cookie)
 | |
| {
 | |
| 	struct page *cpage = NULL;
 | |
| 	char *caddr, *paddr = NULL;
 | |
| 	struct ext4_str cstr, pstr;
 | |
| 	struct inode *inode = d_inode(dentry);
 | |
| 	struct ext4_encrypted_symlink_data *sd;
 | |
| 	loff_t size = min_t(loff_t, i_size_read(inode), PAGE_SIZE - 1);
 | |
| 	int res;
 | |
| 	u32 plen, max_size = inode->i_sb->s_blocksize;
 | |
| 
 | |
| 	res = ext4_get_encryption_info(inode);
 | |
| 	if (res)
 | |
| 		return ERR_PTR(res);
 | |
| 
 | |
| 	if (ext4_inode_is_fast_symlink(inode)) {
 | |
| 		caddr = (char *) EXT4_I(inode)->i_data;
 | |
| 		max_size = sizeof(EXT4_I(inode)->i_data);
 | |
| 	} else {
 | |
| 		cpage = read_mapping_page(inode->i_mapping, 0, NULL);
 | |
| 		if (IS_ERR(cpage))
 | |
| 			return ERR_CAST(cpage);
 | |
| 		caddr = kmap(cpage);
 | |
| 		caddr[size] = 0;
 | |
| 	}
 | |
| 
 | |
| 	/* Symlink is encrypted */
 | |
| 	sd = (struct ext4_encrypted_symlink_data *)caddr;
 | |
| 	cstr.name = sd->encrypted_path;
 | |
| 	cstr.len  = le32_to_cpu(sd->len);
 | |
| 	if ((cstr.len +
 | |
| 	     sizeof(struct ext4_encrypted_symlink_data) - 1) >
 | |
| 	    max_size) {
 | |
| 		/* Symlink data on the disk is corrupted */
 | |
| 		res = -EIO;
 | |
| 		goto errout;
 | |
| 	}
 | |
| 	plen = (cstr.len < EXT4_FNAME_CRYPTO_DIGEST_SIZE*2) ?
 | |
| 		EXT4_FNAME_CRYPTO_DIGEST_SIZE*2 : cstr.len;
 | |
| 	paddr = kmalloc(plen + 1, GFP_NOFS);
 | |
| 	if (!paddr) {
 | |
| 		res = -ENOMEM;
 | |
| 		goto errout;
 | |
| 	}
 | |
| 	pstr.name = paddr;
 | |
| 	pstr.len = plen;
 | |
| 	res = _ext4_fname_disk_to_usr(inode, NULL, &cstr, &pstr);
 | |
| 	if (res < 0)
 | |
| 		goto errout;
 | |
| 	/* Null-terminate the name */
 | |
| 	if (res <= plen)
 | |
| 		paddr[res] = '\0';
 | |
| 	if (cpage) {
 | |
| 		kunmap(cpage);
 | |
| 		page_cache_release(cpage);
 | |
| 	}
 | |
| 	return *cookie = paddr;
 | |
| errout:
 | |
| 	if (cpage) {
 | |
| 		kunmap(cpage);
 | |
| 		page_cache_release(cpage);
 | |
| 	}
 | |
| 	kfree(paddr);
 | |
| 	return ERR_PTR(res);
 | |
| }
 | |
| 
 | |
| const struct inode_operations ext4_encrypted_symlink_inode_operations = {
 | |
| 	.readlink	= generic_readlink,
 | |
| 	.follow_link    = ext4_encrypted_follow_link,
 | |
| 	.put_link       = kfree_put_link,
 | |
| 	.setattr	= ext4_setattr,
 | |
| 	.setxattr	= generic_setxattr,
 | |
| 	.getxattr	= generic_getxattr,
 | |
| 	.listxattr	= ext4_listxattr,
 | |
| 	.removexattr	= generic_removexattr,
 | |
| };
 | |
| #endif
 | |
| 
 | |
| const struct inode_operations ext4_symlink_inode_operations = {
 | |
| 	.readlink	= generic_readlink,
 | |
| 	.follow_link	= page_follow_link_light,
 | |
| 	.put_link	= page_put_link,
 | |
| 	.setattr	= ext4_setattr,
 | |
| 	.setxattr	= generic_setxattr,
 | |
| 	.getxattr	= generic_getxattr,
 | |
| 	.listxattr	= ext4_listxattr,
 | |
| 	.removexattr	= generic_removexattr,
 | |
| };
 | |
| 
 | |
| const struct inode_operations ext4_fast_symlink_inode_operations = {
 | |
| 	.readlink	= generic_readlink,
 | |
| 	.follow_link    = simple_follow_link,
 | |
| 	.setattr	= ext4_setattr,
 | |
| 	.setxattr	= generic_setxattr,
 | |
| 	.getxattr	= generic_getxattr,
 | |
| 	.listxattr	= ext4_listxattr,
 | |
| 	.removexattr	= generic_removexattr,
 | |
| };
 |