mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	vfs-6.12-rc6.fixes
-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCZyTGAQAKCRCRxhvAZXjc
 opd6AQCal4omyfS8FYe4VRRZ/0XHouagq99I0U0TAmKkvoKAsgD/XrdE+pSTEkPX
 Pv4T9phh1cZRxcyKVu77UoYkuHJEDAg=
 =Lu9R
 -----END PGP SIGNATURE-----
Merge tag 'vfs-6.12-rc6.fixes' of gitolite.kernel.org:pub/scm/linux/kernel/git/vfs/vfs
Pull filesystem fixes from Christian Brauner:
 "VFS:
   - Fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP=y is set
   - Add a get_tree_bdev_flags() helper that allows to modify e.g.,
     whether errors are logged into the filesystem context during
     superblock creation. This is used by erofs to fix a userspace
     regression where an error is currently logged when its used on a
     regular file which is an new allowed mode in erofs.
  netfs:
   - Fix the sysfs debug path in the documentation.
   - Fix iov_iter_get_pages*() for folio queues by skipping the page
     extracation if we're at the end of a folio.
  afs:
   - Fix moving subdirectories to different parent directory.
  autofs:
   - Fix handling of AUTOFS_DEV_IOCTL_TIMEOUT_CMD ioctl in
     validate_dev_ioctl(). The actual ioctl number, not the ioctl
     command needs to be checked for autofs"
* tag 'vfs-6.12-rc6.fixes' of gitolite.kernel.org:pub/scm/linux/kernel/git/vfs/vfs:
  iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
  autofs: fix thinko in validate_dev_ioctl()
  iov_iter: Fix iov_iter_get_pages*() for folio_queue
  afs: Fix missing subdir edit when renamed between parent dirs
  doc: correcting the debug path for cachefiles
  erofs: use get_tree_bdev_flags() to avoid misleading messages
  fs/super.c: introduce get_tree_bdev_flags()
			
			
This commit is contained in:
		
						commit
						d56239a82e
					
				
					 10 changed files with 169 additions and 24 deletions
				
			
		| 
						 | 
					@ -115,7 +115,7 @@ set up cache ready for use.  The following script commands are available:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	This mask can also be set through sysfs, eg::
 | 
						This mask can also be set through sysfs, eg::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		echo 5 >/sys/modules/cachefiles/parameters/debug
 | 
							echo 5 > /sys/module/cachefiles/parameters/debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Starting the Cache
 | 
					Starting the Cache
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										25
									
								
								fs/afs/dir.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								fs/afs/dir.c
									
									
									
									
									
								
							| 
						 | 
					@ -12,6 +12,7 @@
 | 
				
			||||||
#include <linux/swap.h>
 | 
					#include <linux/swap.h>
 | 
				
			||||||
#include <linux/ctype.h>
 | 
					#include <linux/ctype.h>
 | 
				
			||||||
#include <linux/sched.h>
 | 
					#include <linux/sched.h>
 | 
				
			||||||
 | 
					#include <linux/iversion.h>
 | 
				
			||||||
#include <linux/task_io_accounting_ops.h>
 | 
					#include <linux/task_io_accounting_ops.h>
 | 
				
			||||||
#include "internal.h"
 | 
					#include "internal.h"
 | 
				
			||||||
#include "afs_fs.h"
 | 
					#include "afs_fs.h"
 | 
				
			||||||
| 
						 | 
					@ -1823,6 +1824,8 @@ static int afs_symlink(struct mnt_idmap *idmap, struct inode *dir,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void afs_rename_success(struct afs_operation *op)
 | 
					static void afs_rename_success(struct afs_operation *op)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct afs_vnode *vnode = AFS_FS_I(d_inode(op->dentry));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_enter("op=%08x", op->debug_id);
 | 
						_enter("op=%08x", op->debug_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	op->ctime = op->file[0].scb.status.mtime_client;
 | 
						op->ctime = op->file[0].scb.status.mtime_client;
 | 
				
			||||||
| 
						 | 
					@ -1832,6 +1835,22 @@ static void afs_rename_success(struct afs_operation *op)
 | 
				
			||||||
		op->ctime = op->file[1].scb.status.mtime_client;
 | 
							op->ctime = op->file[1].scb.status.mtime_client;
 | 
				
			||||||
		afs_vnode_commit_status(op, &op->file[1]);
 | 
							afs_vnode_commit_status(op, &op->file[1]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* If we're moving a subdir between dirs, we need to update
 | 
				
			||||||
 | 
						 * its DV counter too as the ".." will be altered.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (S_ISDIR(vnode->netfs.inode.i_mode) &&
 | 
				
			||||||
 | 
						    op->file[0].vnode != op->file[1].vnode) {
 | 
				
			||||||
 | 
							u64 new_dv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							write_seqlock(&vnode->cb_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							new_dv = vnode->status.data_version + 1;
 | 
				
			||||||
 | 
							vnode->status.data_version = new_dv;
 | 
				
			||||||
 | 
							inode_set_iversion_raw(&vnode->netfs.inode, new_dv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							write_sequnlock(&vnode->cb_lock);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void afs_rename_edit_dir(struct afs_operation *op)
 | 
					static void afs_rename_edit_dir(struct afs_operation *op)
 | 
				
			||||||
| 
						 | 
					@ -1873,6 +1892,12 @@ static void afs_rename_edit_dir(struct afs_operation *op)
 | 
				
			||||||
				 &vnode->fid, afs_edit_dir_for_rename_2);
 | 
									 &vnode->fid, afs_edit_dir_for_rename_2);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (S_ISDIR(vnode->netfs.inode.i_mode) &&
 | 
				
			||||||
 | 
						    new_dvnode != orig_dvnode &&
 | 
				
			||||||
 | 
						    test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
 | 
				
			||||||
 | 
							afs_edit_dir_update_dotdot(vnode, new_dvnode,
 | 
				
			||||||
 | 
										   afs_edit_dir_for_rename_sub);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	new_inode = d_inode(new_dentry);
 | 
						new_inode = d_inode(new_dentry);
 | 
				
			||||||
	if (new_inode) {
 | 
						if (new_inode) {
 | 
				
			||||||
		spin_lock(&new_inode->i_lock);
 | 
							spin_lock(&new_inode->i_lock);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -127,10 +127,10 @@ static struct folio *afs_dir_get_folio(struct afs_vnode *vnode, pgoff_t index)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Scan a directory block looking for a dirent of the right name.
 | 
					 * Scan a directory block looking for a dirent of the right name.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int afs_dir_scan_block(union afs_xdr_dir_block *block, struct qstr *name,
 | 
					static int afs_dir_scan_block(const union afs_xdr_dir_block *block, const struct qstr *name,
 | 
				
			||||||
			      unsigned int blocknum)
 | 
								      unsigned int blocknum)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	union afs_xdr_dirent *de;
 | 
						const union afs_xdr_dirent *de;
 | 
				
			||||||
	u64 bitmap;
 | 
						u64 bitmap;
 | 
				
			||||||
	int d, len, n;
 | 
						int d, len, n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -492,3 +492,90 @@ void afs_edit_dir_remove(struct afs_vnode *vnode,
 | 
				
			||||||
	clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
 | 
						clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
 | 
				
			||||||
	goto out_unmap;
 | 
						goto out_unmap;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Edit a subdirectory that has been moved between directories to update the
 | 
				
			||||||
 | 
					 * ".." entry.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode,
 | 
				
			||||||
 | 
									enum afs_edit_dir_reason why)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						union afs_xdr_dir_block *block;
 | 
				
			||||||
 | 
						union afs_xdr_dirent *de;
 | 
				
			||||||
 | 
						struct folio *folio;
 | 
				
			||||||
 | 
						unsigned int nr_blocks, b;
 | 
				
			||||||
 | 
						pgoff_t index;
 | 
				
			||||||
 | 
						loff_t i_size;
 | 
				
			||||||
 | 
						int slot;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_enter("");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						i_size = i_size_read(&vnode->netfs.inode);
 | 
				
			||||||
 | 
						if (i_size < AFS_DIR_BLOCK_SIZE) {
 | 
				
			||||||
 | 
							clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						nr_blocks = i_size / AFS_DIR_BLOCK_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Find a block that has sufficient slots available.  Each folio
 | 
				
			||||||
 | 
						 * contains two or more directory blocks.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						for (b = 0; b < nr_blocks; b++) {
 | 
				
			||||||
 | 
							index = b / AFS_DIR_BLOCKS_PER_PAGE;
 | 
				
			||||||
 | 
							folio = afs_dir_get_folio(vnode, index);
 | 
				
			||||||
 | 
							if (!folio)
 | 
				
			||||||
 | 
								goto error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							block = kmap_local_folio(folio, b * AFS_DIR_BLOCK_SIZE - folio_pos(folio));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Abandon the edit if we got a callback break. */
 | 
				
			||||||
 | 
							if (!test_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
 | 
				
			||||||
 | 
								goto invalidated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							slot = afs_dir_scan_block(block, &dotdot_name, b);
 | 
				
			||||||
 | 
							if (slot >= 0)
 | 
				
			||||||
 | 
								goto found_dirent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							kunmap_local(block);
 | 
				
			||||||
 | 
							folio_unlock(folio);
 | 
				
			||||||
 | 
							folio_put(folio);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Didn't find the dirent to clobber.  Download the directory again. */
 | 
				
			||||||
 | 
						trace_afs_edit_dir(vnode, why, afs_edit_dir_update_nodd,
 | 
				
			||||||
 | 
								   0, 0, 0, 0, "..");
 | 
				
			||||||
 | 
						clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
 | 
				
			||||||
 | 
						goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					found_dirent:
 | 
				
			||||||
 | 
						de = &block->dirents[slot];
 | 
				
			||||||
 | 
						de->u.vnode  = htonl(new_dvnode->fid.vnode);
 | 
				
			||||||
 | 
						de->u.unique = htonl(new_dvnode->fid.unique);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						trace_afs_edit_dir(vnode, why, afs_edit_dir_update_dd, b, slot,
 | 
				
			||||||
 | 
								   ntohl(de->u.vnode), ntohl(de->u.unique), "..");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						kunmap_local(block);
 | 
				
			||||||
 | 
						folio_unlock(folio);
 | 
				
			||||||
 | 
						folio_put(folio);
 | 
				
			||||||
 | 
						inode_set_iversion_raw(&vnode->netfs.inode, vnode->status.data_version);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						_leave("");
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					invalidated:
 | 
				
			||||||
 | 
						kunmap_local(block);
 | 
				
			||||||
 | 
						folio_unlock(folio);
 | 
				
			||||||
 | 
						folio_put(folio);
 | 
				
			||||||
 | 
						trace_afs_edit_dir(vnode, why, afs_edit_dir_update_inval,
 | 
				
			||||||
 | 
								   0, 0, 0, 0, "..");
 | 
				
			||||||
 | 
						clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
 | 
				
			||||||
 | 
						goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error:
 | 
				
			||||||
 | 
						trace_afs_edit_dir(vnode, why, afs_edit_dir_update_error,
 | 
				
			||||||
 | 
								   0, 0, 0, 0, "..");
 | 
				
			||||||
 | 
						clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags);
 | 
				
			||||||
 | 
						goto out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1073,6 +1073,8 @@ extern void afs_check_for_remote_deletion(struct afs_operation *);
 | 
				
			||||||
extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *,
 | 
					extern void afs_edit_dir_add(struct afs_vnode *, struct qstr *, struct afs_fid *,
 | 
				
			||||||
			     enum afs_edit_dir_reason);
 | 
								     enum afs_edit_dir_reason);
 | 
				
			||||||
extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason);
 | 
					extern void afs_edit_dir_remove(struct afs_vnode *, struct qstr *, enum afs_edit_dir_reason);
 | 
				
			||||||
 | 
					void afs_edit_dir_update_dotdot(struct afs_vnode *vnode, struct afs_vnode *new_dvnode,
 | 
				
			||||||
 | 
									enum afs_edit_dir_reason why);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * dir_silly.c
 | 
					 * dir_silly.c
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -110,6 +110,7 @@ static inline void free_dev_ioctl(struct autofs_dev_ioctl *param)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
 | 
					static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						unsigned int inr = _IOC_NR(cmd);
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = check_dev_ioctl_version(cmd, param);
 | 
						err = check_dev_ioctl_version(cmd, param);
 | 
				
			||||||
| 
						 | 
					@ -133,7 +134,7 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
 | 
				
			||||||
		 * check_name() return for AUTOFS_DEV_IOCTL_TIMEOUT_CMD.
 | 
							 * check_name() return for AUTOFS_DEV_IOCTL_TIMEOUT_CMD.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		err = check_name(param->path);
 | 
							err = check_name(param->path);
 | 
				
			||||||
		if (cmd == AUTOFS_DEV_IOCTL_TIMEOUT_CMD)
 | 
							if (inr == AUTOFS_DEV_IOCTL_TIMEOUT_CMD)
 | 
				
			||||||
			err = err ? 0 : -EINVAL;
 | 
								err = err ? 0 : -EINVAL;
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
			pr_warn("invalid path supplied for cmd(0x%08x)\n",
 | 
								pr_warn("invalid path supplied for cmd(0x%08x)\n",
 | 
				
			||||||
| 
						 | 
					@ -141,8 +142,6 @@ static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
 | 
				
			||||||
			goto out;
 | 
								goto out;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		unsigned int inr = _IOC_NR(cmd);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (inr == AUTOFS_DEV_IOCTL_OPENMOUNT_CMD ||
 | 
							if (inr == AUTOFS_DEV_IOCTL_OPENMOUNT_CMD ||
 | 
				
			||||||
		    inr == AUTOFS_DEV_IOCTL_REQUESTER_CMD ||
 | 
							    inr == AUTOFS_DEV_IOCTL_REQUESTER_CMD ||
 | 
				
			||||||
		    inr == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) {
 | 
							    inr == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -709,7 +709,9 @@ static int erofs_fc_get_tree(struct fs_context *fc)
 | 
				
			||||||
	if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
 | 
						if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
 | 
				
			||||||
		return get_tree_nodev(fc, erofs_fc_fill_super);
 | 
							return get_tree_nodev(fc, erofs_fc_fill_super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = get_tree_bdev(fc, erofs_fc_fill_super);
 | 
						ret = get_tree_bdev_flags(fc, erofs_fc_fill_super,
 | 
				
			||||||
 | 
							IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) ?
 | 
				
			||||||
 | 
								GET_TREE_BDEV_QUIET_LOOKUP : 0);
 | 
				
			||||||
#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE
 | 
					#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE
 | 
				
			||||||
	if (ret == -ENOTBLK) {
 | 
						if (ret == -ENOTBLK) {
 | 
				
			||||||
		if (!fc->source)
 | 
							if (!fc->source)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										26
									
								
								fs/super.c
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								fs/super.c
									
									
									
									
									
								
							| 
						 | 
					@ -1596,13 +1596,14 @@ int setup_bdev_super(struct super_block *sb, int sb_flags,
 | 
				
			||||||
EXPORT_SYMBOL_GPL(setup_bdev_super);
 | 
					EXPORT_SYMBOL_GPL(setup_bdev_super);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * get_tree_bdev - Get a superblock based on a single block device
 | 
					 * get_tree_bdev_flags - Get a superblock based on a single block device
 | 
				
			||||||
 * @fc: The filesystem context holding the parameters
 | 
					 * @fc: The filesystem context holding the parameters
 | 
				
			||||||
 * @fill_super: Helper to initialise a new superblock
 | 
					 * @fill_super: Helper to initialise a new superblock
 | 
				
			||||||
 | 
					 * @flags: GET_TREE_BDEV_* flags
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
int get_tree_bdev(struct fs_context *fc,
 | 
					int get_tree_bdev_flags(struct fs_context *fc,
 | 
				
			||||||
		int (*fill_super)(struct super_block *,
 | 
							int (*fill_super)(struct super_block *sb,
 | 
				
			||||||
				  struct fs_context *))
 | 
									  struct fs_context *fc), unsigned int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct super_block *s;
 | 
						struct super_block *s;
 | 
				
			||||||
	int error = 0;
 | 
						int error = 0;
 | 
				
			||||||
| 
						 | 
					@ -1613,10 +1614,10 @@ int get_tree_bdev(struct fs_context *fc,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	error = lookup_bdev(fc->source, &dev);
 | 
						error = lookup_bdev(fc->source, &dev);
 | 
				
			||||||
	if (error) {
 | 
						if (error) {
 | 
				
			||||||
		errorf(fc, "%s: Can't lookup blockdev", fc->source);
 | 
							if (!(flags & GET_TREE_BDEV_QUIET_LOOKUP))
 | 
				
			||||||
 | 
								errorf(fc, "%s: Can't lookup blockdev", fc->source);
 | 
				
			||||||
		return error;
 | 
							return error;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	fc->sb_flags |= SB_NOSEC;
 | 
						fc->sb_flags |= SB_NOSEC;
 | 
				
			||||||
	s = sget_dev(fc, dev);
 | 
						s = sget_dev(fc, dev);
 | 
				
			||||||
	if (IS_ERR(s))
 | 
						if (IS_ERR(s))
 | 
				
			||||||
| 
						 | 
					@ -1644,6 +1645,19 @@ int get_tree_bdev(struct fs_context *fc,
 | 
				
			||||||
	fc->root = dget(s->s_root);
 | 
						fc->root = dget(s->s_root);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL_GPL(get_tree_bdev_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * get_tree_bdev - Get a superblock based on a single block device
 | 
				
			||||||
 | 
					 * @fc: The filesystem context holding the parameters
 | 
				
			||||||
 | 
					 * @fill_super: Helper to initialise a new superblock
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					int get_tree_bdev(struct fs_context *fc,
 | 
				
			||||||
 | 
							int (*fill_super)(struct super_block *,
 | 
				
			||||||
 | 
									  struct fs_context *))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return get_tree_bdev_flags(fc, fill_super, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(get_tree_bdev);
 | 
					EXPORT_SYMBOL(get_tree_bdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int test_bdev_super(struct super_block *s, void *data)
 | 
					static int test_bdev_super(struct super_block *s, void *data)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,6 +160,12 @@ extern int get_tree_keyed(struct fs_context *fc,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int setup_bdev_super(struct super_block *sb, int sb_flags,
 | 
					int setup_bdev_super(struct super_block *sb, int sb_flags,
 | 
				
			||||||
		struct fs_context *fc);
 | 
							struct fs_context *fc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define GET_TREE_BDEV_QUIET_LOOKUP		0x0001
 | 
				
			||||||
 | 
					int get_tree_bdev_flags(struct fs_context *fc,
 | 
				
			||||||
 | 
							int (*fill_super)(struct super_block *sb,
 | 
				
			||||||
 | 
									  struct fs_context *fc), unsigned int flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int get_tree_bdev(struct fs_context *fc,
 | 
					extern int get_tree_bdev(struct fs_context *fc,
 | 
				
			||||||
			       int (*fill_super)(struct super_block *sb,
 | 
								       int (*fill_super)(struct super_block *sb,
 | 
				
			||||||
						 struct fs_context *fc));
 | 
											 struct fs_context *fc));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -331,7 +331,11 @@ enum yfs_cm_operation {
 | 
				
			||||||
	EM(afs_edit_dir_delete,			"delete") \
 | 
						EM(afs_edit_dir_delete,			"delete") \
 | 
				
			||||||
	EM(afs_edit_dir_delete_error,		"d_err ") \
 | 
						EM(afs_edit_dir_delete_error,		"d_err ") \
 | 
				
			||||||
	EM(afs_edit_dir_delete_inval,		"d_invl") \
 | 
						EM(afs_edit_dir_delete_inval,		"d_invl") \
 | 
				
			||||||
	E_(afs_edit_dir_delete_noent,		"d_nent")
 | 
						EM(afs_edit_dir_delete_noent,		"d_nent") \
 | 
				
			||||||
 | 
						EM(afs_edit_dir_update_dd,		"u_ddot") \
 | 
				
			||||||
 | 
						EM(afs_edit_dir_update_error,		"u_fail") \
 | 
				
			||||||
 | 
						EM(afs_edit_dir_update_inval,		"u_invl") \
 | 
				
			||||||
 | 
						E_(afs_edit_dir_update_nodd,		"u_nodd")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define afs_edit_dir_reasons				  \
 | 
					#define afs_edit_dir_reasons				  \
 | 
				
			||||||
	EM(afs_edit_dir_for_create,		"Create") \
 | 
						EM(afs_edit_dir_for_create,		"Create") \
 | 
				
			||||||
| 
						 | 
					@ -340,6 +344,7 @@ enum yfs_cm_operation {
 | 
				
			||||||
	EM(afs_edit_dir_for_rename_0,		"Renam0") \
 | 
						EM(afs_edit_dir_for_rename_0,		"Renam0") \
 | 
				
			||||||
	EM(afs_edit_dir_for_rename_1,		"Renam1") \
 | 
						EM(afs_edit_dir_for_rename_1,		"Renam1") \
 | 
				
			||||||
	EM(afs_edit_dir_for_rename_2,		"Renam2") \
 | 
						EM(afs_edit_dir_for_rename_2,		"Renam2") \
 | 
				
			||||||
 | 
						EM(afs_edit_dir_for_rename_sub,		"RnmSub") \
 | 
				
			||||||
	EM(afs_edit_dir_for_rmdir,		"RmDir ") \
 | 
						EM(afs_edit_dir_for_rmdir,		"RmDir ") \
 | 
				
			||||||
	EM(afs_edit_dir_for_silly_0,		"S_Ren0") \
 | 
						EM(afs_edit_dir_for_silly_0,		"S_Ren0") \
 | 
				
			||||||
	EM(afs_edit_dir_for_silly_1,		"S_Ren1") \
 | 
						EM(afs_edit_dir_for_silly_1,		"S_Ren1") \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -461,6 +461,8 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
 | 
				
			||||||
		size_t bytes, struct iov_iter *i)
 | 
							size_t bytes, struct iov_iter *i)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	size_t n, copied = 0;
 | 
						size_t n, copied = 0;
 | 
				
			||||||
 | 
						bool uses_kmap = IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP) ||
 | 
				
			||||||
 | 
								 PageHighMem(page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!page_copy_sane(page, offset, bytes))
 | 
						if (!page_copy_sane(page, offset, bytes))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					@ -471,7 +473,7 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
 | 
				
			||||||
		char *p;
 | 
							char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		n = bytes - copied;
 | 
							n = bytes - copied;
 | 
				
			||||||
		if (PageHighMem(page)) {
 | 
							if (uses_kmap) {
 | 
				
			||||||
			page += offset / PAGE_SIZE;
 | 
								page += offset / PAGE_SIZE;
 | 
				
			||||||
			offset %= PAGE_SIZE;
 | 
								offset %= PAGE_SIZE;
 | 
				
			||||||
			n = min_t(size_t, n, PAGE_SIZE - offset);
 | 
								n = min_t(size_t, n, PAGE_SIZE - offset);
 | 
				
			||||||
| 
						 | 
					@ -482,7 +484,7 @@ size_t copy_page_from_iter_atomic(struct page *page, size_t offset,
 | 
				
			||||||
		kunmap_atomic(p);
 | 
							kunmap_atomic(p);
 | 
				
			||||||
		copied += n;
 | 
							copied += n;
 | 
				
			||||||
		offset += n;
 | 
							offset += n;
 | 
				
			||||||
	} while (PageHighMem(page) && copied != bytes && n > 0);
 | 
						} while (uses_kmap && copied != bytes && n > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return copied;
 | 
						return copied;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1021,15 +1023,18 @@ static ssize_t iter_folioq_get_pages(struct iov_iter *iter,
 | 
				
			||||||
		size_t offset = iov_offset, fsize = folioq_folio_size(folioq, slot);
 | 
							size_t offset = iov_offset, fsize = folioq_folio_size(folioq, slot);
 | 
				
			||||||
		size_t part = PAGE_SIZE - offset % PAGE_SIZE;
 | 
							size_t part = PAGE_SIZE - offset % PAGE_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		part = umin(part, umin(maxsize - extracted, fsize - offset));
 | 
							if (offset < fsize) {
 | 
				
			||||||
		count -= part;
 | 
								part = umin(part, umin(maxsize - extracted, fsize - offset));
 | 
				
			||||||
		iov_offset += part;
 | 
								count -= part;
 | 
				
			||||||
		extracted += part;
 | 
								iov_offset += part;
 | 
				
			||||||
 | 
								extracted += part;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								*pages = folio_page(folio, offset / PAGE_SIZE);
 | 
				
			||||||
 | 
								get_page(*pages);
 | 
				
			||||||
 | 
								pages++;
 | 
				
			||||||
 | 
								maxpages--;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		*pages = folio_page(folio, offset / PAGE_SIZE);
 | 
					 | 
				
			||||||
		get_page(*pages);
 | 
					 | 
				
			||||||
		pages++;
 | 
					 | 
				
			||||||
		maxpages--;
 | 
					 | 
				
			||||||
		if (maxpages == 0 || extracted >= maxsize)
 | 
							if (maxpages == 0 || extracted >= maxsize)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue