File Index
Files and directories
Sign in
FILE

hostfs_kern.c

File preview with syntax highlighting.

linux-6.19.14/fs/hostfs/hostfs_kern.c C
   1/*
   2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
   3 * Licensed under the GPL
   4 *
   5 * Ported the filesystem routines to 2.5.
   6 * 2003-02-10 Petr Baudis <pasky@ucw.cz>
   7 */
   8
   9#include <linux/fs.h>
  10#include <linux/magic.h>
  11#include <linux/module.h>
  12#include <linux/mm.h>
  13#include <linux/pagemap.h>
  14#include <linux/statfs.h>
  15#include <linux/slab.h>
  16#include <linux/seq_file.h>
  17#include <linux/writeback.h>
  18#include <linux/mount.h>
  19#include <linux/fs_context.h>
  20#include <linux/fs_parser.h>
  21#include <linux/namei.h>
  22#include "hostfs.h"
  23#include <init.h>
  24#include <kern.h>
  25
  26struct hostfs_fs_info {
  27	char *host_root_path;
  28};
  29
  30struct hostfs_inode_info {
  31	int fd;
  32	fmode_t mode;
  33	struct inode vfs_inode;
  34	struct mutex open_mutex;
  35	dev_t dev;
  36	struct hostfs_timespec btime;
  37};
  38
  39static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
  40{
  41	return list_entry(inode, struct hostfs_inode_info, vfs_inode);
  42}
  43
  44#define FILE_HOSTFS_I(file) HOSTFS_I(file_inode(file))
  45
  46static struct kmem_cache *hostfs_inode_cache;
  47
  48/* Changed in hostfs_args before the kernel starts running */
  49static char *root_ino = "";
  50static int append = 0;
  51
  52static const struct inode_operations hostfs_iops;
  53static const struct inode_operations hostfs_dir_iops;
  54static const struct inode_operations hostfs_link_iops;
  55
  56#ifndef MODULE
  57static int __init hostfs_args(char *options, int *add)
  58{
  59	char *ptr;
  60
  61	*add = 0;
  62	ptr = strchr(options, ',');
  63	if (ptr != NULL)
  64		*ptr++ = '\0';
  65	if (*options != '\0')
  66		root_ino = options;
  67
  68	options = ptr;
  69	while (options) {
  70		ptr = strchr(options, ',');
  71		if (ptr != NULL)
  72			*ptr++ = '\0';
  73		if (*options != '\0') {
  74			if (!strcmp(options, "append"))
  75				append = 1;
  76			else printf("hostfs_args - unsupported option - %s\n",
  77				    options);
  78		}
  79		options = ptr;
  80	}
  81	return 0;
  82}
  83
  84__uml_setup("hostfs=", hostfs_args,
  85"hostfs=<root dir>,<flags>,...\n"
  86"    This is used to set hostfs parameters.  The root directory argument\n"
  87"    is used to confine all hostfs mounts to within the specified directory\n"
  88"    tree on the host.  If this isn't specified, then a user inside UML can\n"
  89"    mount anything on the host that's accessible to the user that's running\n"
  90"    it.\n"
  91"    The only flag currently supported is 'append', which specifies that all\n"
  92"    files opened by hostfs will be opened in append mode.\n\n"
  93);
  94#endif
  95
  96static char *__dentry_name(struct dentry *dentry, char *name)
  97{
  98	char *p = dentry_path_raw(dentry, name, PATH_MAX);
  99	struct hostfs_fs_info *fsi = dentry->d_sb->s_fs_info;
 100	char *root = fsi->host_root_path;
 101	size_t len = strlen(root);
 102
 103	if (IS_ERR(p) || len > p - name) {
 104		__putname(name);
 105		return NULL;
 106	}
 107
 108	memcpy(name, root, len);
 109	memmove(name + len, p, name + PATH_MAX - p);
 110
 111	return name;
 112}
 113
 114static char *dentry_name(struct dentry *dentry)
 115{
 116	char *name = __getname();
 117	if (!name)
 118		return NULL;
 119
 120	return __dentry_name(dentry, name);
 121}
 122
 123static char *inode_name(struct inode *ino)
 124{
 125	struct dentry *dentry;
 126	char *name;
 127
 128	dentry = d_find_alias(ino);
 129	if (!dentry)
 130		return NULL;
 131
 132	name = dentry_name(dentry);
 133
 134	dput(dentry);
 135
 136	return name;
 137}
 138
 139static char *follow_link(char *link)
 140{
 141	char *name, *resolved, *end;
 142	int n;
 143
 144	name = kmalloc(PATH_MAX, GFP_KERNEL);
 145	if (!name) {
 146		n = -ENOMEM;
 147		goto out_free;
 148	}
 149
 150	n = hostfs_do_readlink(link, name, PATH_MAX);
 151	if (n < 0)
 152		goto out_free;
 153	else if (n == PATH_MAX) {
 154		n = -E2BIG;
 155		goto out_free;
 156	}
 157
 158	if (*name == '/')
 159		return name;
 160
 161	end = strrchr(link, '/');
 162	if (end == NULL)
 163		return name;
 164
 165	*(end + 1) = '\0';
 166
 167	resolved = kasprintf(GFP_KERNEL, "%s%s", link, name);
 168	if (resolved == NULL) {
 169		n = -ENOMEM;
 170		goto out_free;
 171	}
 172
 173	kfree(name);
 174	return resolved;
 175
 176 out_free:
 177	kfree(name);
 178	return ERR_PTR(n);
 179}
 180
 181static int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
 182{
 183	/*
 184	 * do_statfs uses struct statfs64 internally, but the linux kernel
 185	 * struct statfs still has 32-bit versions for most of these fields,
 186	 * so we convert them here
 187	 */
 188	int err;
 189	long long f_blocks;
 190	long long f_bfree;
 191	long long f_bavail;
 192	long long f_files;
 193	long long f_ffree;
 194	struct hostfs_fs_info *fsi;
 195
 196	fsi = dentry->d_sb->s_fs_info;
 197	err = do_statfs(fsi->host_root_path,
 198			&sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
 199			&f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
 200			&sf->f_namelen);
 201	if (err)
 202		return err;
 203	sf->f_blocks = f_blocks;
 204	sf->f_bfree = f_bfree;
 205	sf->f_bavail = f_bavail;
 206	sf->f_files = f_files;
 207	sf->f_ffree = f_ffree;
 208	sf->f_type = HOSTFS_SUPER_MAGIC;
 209	return 0;
 210}
 211
 212static struct inode *hostfs_alloc_inode(struct super_block *sb)
 213{
 214	struct hostfs_inode_info *hi;
 215
 216	hi = alloc_inode_sb(sb, hostfs_inode_cache, GFP_KERNEL_ACCOUNT);
 217	if (hi == NULL)
 218		return NULL;
 219	hi->fd = -1;
 220	hi->mode = 0;
 221	hi->dev = 0;
 222	inode_init_once(&hi->vfs_inode);
 223	mutex_init(&hi->open_mutex);
 224	return &hi->vfs_inode;
 225}
 226
 227static void hostfs_evict_inode(struct inode *inode)
 228{
 229	truncate_inode_pages_final(&inode->i_data);
 230	clear_inode(inode);
 231	if (HOSTFS_I(inode)->fd != -1) {
 232		close_file(&HOSTFS_I(inode)->fd);
 233		HOSTFS_I(inode)->fd = -1;
 234		HOSTFS_I(inode)->dev = 0;
 235	}
 236}
 237
 238static void hostfs_free_inode(struct inode *inode)
 239{
 240	kmem_cache_free(hostfs_inode_cache, HOSTFS_I(inode));
 241}
 242
 243static int hostfs_show_options(struct seq_file *seq, struct dentry *root)
 244{
 245	struct hostfs_fs_info *fsi;
 246	const char *root_path;
 247
 248	fsi = root->d_sb->s_fs_info;
 249	root_path = fsi->host_root_path;
 250	size_t offset = strlen(root_ino) + 1;
 251
 252	if (strlen(root_path) > offset)
 253		seq_show_option(seq, root_path + offset, NULL);
 254
 255	if (append)
 256		seq_puts(seq, ",append");
 257
 258	return 0;
 259}
 260
 261static const struct super_operations hostfs_sbops = {
 262	.alloc_inode	= hostfs_alloc_inode,
 263	.free_inode	= hostfs_free_inode,
 264	.drop_inode	= inode_just_drop,
 265	.evict_inode	= hostfs_evict_inode,
 266	.statfs		= hostfs_statfs,
 267	.show_options	= hostfs_show_options,
 268};
 269
 270static int hostfs_readdir(struct file *file, struct dir_context *ctx)
 271{
 272	void *dir;
 273	char *name;
 274	unsigned long long next, ino;
 275	int error, len;
 276	unsigned int type;
 277
 278	name = dentry_name(file->f_path.dentry);
 279	if (name == NULL)
 280		return -ENOMEM;
 281	dir = open_dir(name, &error);
 282	__putname(name);
 283	if (dir == NULL)
 284		return -error;
 285	next = ctx->pos;
 286	seek_dir(dir, next);
 287	while ((name = read_dir(dir, &next, &ino, &len, &type)) != NULL) {
 288		if (!dir_emit(ctx, name, len, ino, type))
 289			break;
 290		ctx->pos = next;
 291	}
 292	close_dir(dir);
 293	return 0;
 294}
 295
 296static int hostfs_open(struct inode *ino, struct file *file)
 297{
 298	char *name;
 299	fmode_t mode;
 300	int err;
 301	int r, w, fd;
 302
 303	mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
 304	if ((mode & HOSTFS_I(ino)->mode) == mode)
 305		return 0;
 306
 307	mode |= HOSTFS_I(ino)->mode;
 308
 309retry:
 310	r = w = 0;
 311
 312	if (mode & FMODE_READ)
 313		r = 1;
 314	if (mode & FMODE_WRITE)
 315		r = w = 1;
 316
 317	name = dentry_name(file_dentry(file));
 318	if (name == NULL)
 319		return -ENOMEM;
 320
 321	fd = open_file(name, r, w, append);
 322	__putname(name);
 323	if (fd < 0)
 324		return fd;
 325
 326	mutex_lock(&HOSTFS_I(ino)->open_mutex);
 327	/* somebody else had handled it first? */
 328	if ((mode & HOSTFS_I(ino)->mode) == mode) {
 329		mutex_unlock(&HOSTFS_I(ino)->open_mutex);
 330		close_file(&fd);
 331		return 0;
 332	}
 333	if ((mode | HOSTFS_I(ino)->mode) != mode) {
 334		mode |= HOSTFS_I(ino)->mode;
 335		mutex_unlock(&HOSTFS_I(ino)->open_mutex);
 336		close_file(&fd);
 337		goto retry;
 338	}
 339	if (HOSTFS_I(ino)->fd == -1) {
 340		HOSTFS_I(ino)->fd = fd;
 341	} else {
 342		err = replace_file(fd, HOSTFS_I(ino)->fd);
 343		close_file(&fd);
 344		if (err < 0) {
 345			mutex_unlock(&HOSTFS_I(ino)->open_mutex);
 346			return err;
 347		}
 348	}
 349	HOSTFS_I(ino)->mode = mode;
 350	mutex_unlock(&HOSTFS_I(ino)->open_mutex);
 351
 352	return 0;
 353}
 354
 355static int hostfs_file_release(struct inode *inode, struct file *file)
 356{
 357	filemap_write_and_wait(inode->i_mapping);
 358
 359	return 0;
 360}
 361
 362static int hostfs_fsync(struct file *file, loff_t start, loff_t end,
 363			int datasync)
 364{
 365	struct inode *inode = file->f_mapping->host;
 366	int ret;
 367
 368	ret = file_write_and_wait_range(file, start, end);
 369	if (ret)
 370		return ret;
 371
 372	inode_lock(inode);
 373	ret = fsync_file(HOSTFS_I(inode)->fd, datasync);
 374	inode_unlock(inode);
 375
 376	return ret;
 377}
 378
 379static const struct file_operations hostfs_file_fops = {
 380	.llseek		= generic_file_llseek,
 381	.splice_read	= filemap_splice_read,
 382	.splice_write	= iter_file_splice_write,
 383	.read_iter	= generic_file_read_iter,
 384	.write_iter	= generic_file_write_iter,
 385	.mmap_prepare	= generic_file_mmap_prepare,
 386	.open		= hostfs_open,
 387	.release	= hostfs_file_release,
 388	.fsync		= hostfs_fsync,
 389};
 390
 391static const struct file_operations hostfs_dir_fops = {
 392	.llseek		= generic_file_llseek,
 393	.iterate_shared	= hostfs_readdir,
 394	.read		= generic_read_dir,
 395	.open		= hostfs_open,
 396	.fsync		= hostfs_fsync,
 397};
 398
 399static int hostfs_writepages(struct address_space *mapping,
 400		struct writeback_control *wbc)
 401{
 402	struct inode *inode = mapping->host;
 403	struct folio *folio = NULL;
 404	loff_t i_size = i_size_read(inode);
 405	int err = 0;
 406
 407	while ((folio = writeback_iter(mapping, wbc, folio, &err))) {
 408		loff_t pos = folio_pos(folio);
 409		size_t count = folio_size(folio);
 410		char *buffer;
 411		int ret;
 412
 413		if (count > i_size - pos)
 414			count = i_size - pos;
 415
 416		buffer = kmap_local_folio(folio, 0);
 417		ret = write_file(HOSTFS_I(inode)->fd, &pos, buffer, count);
 418		kunmap_local(buffer);
 419		folio_unlock(folio);
 420		if (ret != count) {
 421			err = ret < 0 ? ret : -EIO;
 422			mapping_set_error(mapping, err);
 423		}
 424	}
 425
 426	return err;
 427}
 428
 429static int hostfs_read_folio(struct file *file, struct folio *folio)
 430{
 431	char *buffer;
 432	loff_t start = folio_pos(folio);
 433	int bytes_read, ret = 0;
 434
 435	buffer = kmap_local_folio(folio, 0);
 436	bytes_read = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
 437			PAGE_SIZE);
 438	if (bytes_read < 0)
 439		ret = bytes_read;
 440	else
 441		buffer = folio_zero_tail(folio, bytes_read, buffer + bytes_read);
 442	kunmap_local(buffer);
 443
 444	folio_end_read(folio, ret == 0);
 445	return ret;
 446}
 447
 448static int hostfs_write_begin(const struct kiocb *iocb,
 449			      struct address_space *mapping,
 450			      loff_t pos, unsigned len,
 451			      struct folio **foliop, void **fsdata)
 452{
 453	pgoff_t index = pos >> PAGE_SHIFT;
 454
 455	*foliop = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN,
 456			mapping_gfp_mask(mapping));
 457	if (IS_ERR(*foliop))
 458		return PTR_ERR(*foliop);
 459	return 0;
 460}
 461
 462static int hostfs_write_end(const struct kiocb *iocb,
 463			    struct address_space *mapping,
 464			    loff_t pos, unsigned len, unsigned copied,
 465			    struct folio *folio, void *fsdata)
 466{
 467	struct inode *inode = mapping->host;
 468	void *buffer;
 469	size_t from = offset_in_folio(folio, pos);
 470	int err;
 471
 472	buffer = kmap_local_folio(folio, from);
 473	err = write_file(FILE_HOSTFS_I(iocb->ki_filp)->fd, &pos, buffer, copied);
 474	kunmap_local(buffer);
 475
 476	if (!folio_test_uptodate(folio) && err == folio_size(folio))
 477		folio_mark_uptodate(folio);
 478
 479	/*
 480	 * If err > 0, write_file has added err to pos, so we are comparing
 481	 * i_size against the last byte written.
 482	 */
 483	if (err > 0 && (pos > inode->i_size))
 484		inode->i_size = pos;
 485	folio_unlock(folio);
 486	folio_put(folio);
 487
 488	return err;
 489}
 490
 491static const struct address_space_operations hostfs_aops = {
 492	.writepages 	= hostfs_writepages,
 493	.read_folio	= hostfs_read_folio,
 494	.dirty_folio	= filemap_dirty_folio,
 495	.write_begin	= hostfs_write_begin,
 496	.write_end	= hostfs_write_end,
 497	.migrate_folio	= filemap_migrate_folio,
 498};
 499
 500static int hostfs_inode_update(struct inode *ino, const struct hostfs_stat *st)
 501{
 502	set_nlink(ino, st->nlink);
 503	i_uid_write(ino, st->uid);
 504	i_gid_write(ino, st->gid);
 505	inode_set_atime_to_ts(ino, (struct timespec64){
 506			st->atime.tv_sec,
 507			st->atime.tv_nsec,
 508		});
 509	inode_set_mtime_to_ts(ino, (struct timespec64){
 510			st->mtime.tv_sec,
 511			st->mtime.tv_nsec,
 512		});
 513	inode_set_ctime(ino, st->ctime.tv_sec, st->ctime.tv_nsec);
 514	ino->i_size = st->size;
 515	ino->i_blocks = st->blocks;
 516	return 0;
 517}
 518
 519static int hostfs_inode_set(struct inode *ino, void *data)
 520{
 521	struct hostfs_stat *st = data;
 522	dev_t dev, rdev;
 523
 524	/* Reencode maj and min with the kernel encoding.*/
 525	rdev = MKDEV(st->rdev.maj, st->rdev.min);
 526	dev = MKDEV(st->dev.maj, st->dev.min);
 527
 528	switch (st->mode & S_IFMT) {
 529	case S_IFLNK:
 530		ino->i_op = &hostfs_link_iops;
 531		break;
 532	case S_IFDIR:
 533		ino->i_op = &hostfs_dir_iops;
 534		ino->i_fop = &hostfs_dir_fops;
 535		break;
 536	case S_IFCHR:
 537	case S_IFBLK:
 538	case S_IFIFO:
 539	case S_IFSOCK:
 540		init_special_inode(ino, st->mode & S_IFMT, rdev);
 541		ino->i_op = &hostfs_iops;
 542		break;
 543	case S_IFREG:
 544		ino->i_op = &hostfs_iops;
 545		ino->i_fop = &hostfs_file_fops;
 546		ino->i_mapping->a_ops = &hostfs_aops;
 547		break;
 548	default:
 549		return -EIO;
 550	}
 551
 552	HOSTFS_I(ino)->dev = dev;
 553	HOSTFS_I(ino)->btime = st->btime;
 554	ino->i_ino = st->ino;
 555	ino->i_mode = st->mode;
 556	return hostfs_inode_update(ino, st);
 557}
 558
 559static int hostfs_inode_test(struct inode *inode, void *data)
 560{
 561	const struct hostfs_stat *st = data;
 562	dev_t dev = MKDEV(st->dev.maj, st->dev.min);
 563
 564	return inode->i_ino == st->ino && HOSTFS_I(inode)->dev == dev &&
 565	       (inode->i_mode & S_IFMT) == (st->mode & S_IFMT) &&
 566	       HOSTFS_I(inode)->btime.tv_sec == st->btime.tv_sec &&
 567	       HOSTFS_I(inode)->btime.tv_nsec == st->btime.tv_nsec;
 568}
 569
 570static struct inode *hostfs_iget(struct super_block *sb, char *name)
 571{
 572	struct inode *inode;
 573	struct hostfs_stat st;
 574	int err = stat_file(name, &st, -1);
 575
 576	if (err)
 577		return ERR_PTR(err);
 578
 579	inode = iget5_locked(sb, st.ino, hostfs_inode_test, hostfs_inode_set,
 580			     &st);
 581	if (!inode)
 582		return ERR_PTR(-ENOMEM);
 583
 584	if (inode_state_read_once(inode) & I_NEW) {
 585		unlock_new_inode(inode);
 586	} else {
 587		spin_lock(&inode->i_lock);
 588		hostfs_inode_update(inode, &st);
 589		spin_unlock(&inode->i_lock);
 590	}
 591
 592	return inode;
 593}
 594
 595static int hostfs_create(struct mnt_idmap *idmap, struct inode *dir,
 596			 struct dentry *dentry, umode_t mode, bool excl)
 597{
 598	struct inode *inode;
 599	char *name;
 600	int fd;
 601
 602	name = dentry_name(dentry);
 603	if (name == NULL)
 604		return -ENOMEM;
 605
 606	fd = file_create(name, mode & 0777);
 607	if (fd < 0) {
 608		__putname(name);
 609		return fd;
 610	}
 611
 612	inode = hostfs_iget(dir->i_sb, name);
 613	__putname(name);
 614	if (IS_ERR(inode))
 615		return PTR_ERR(inode);
 616
 617	HOSTFS_I(inode)->fd = fd;
 618	HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
 619	d_instantiate(dentry, inode);
 620	return 0;
 621}
 622
 623static struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
 624				    unsigned int flags)
 625{
 626	struct inode *inode = NULL;
 627	char *name;
 628
 629	name = dentry_name(dentry);
 630	if (name == NULL)
 631		return ERR_PTR(-ENOMEM);
 632
 633	inode = hostfs_iget(ino->i_sb, name);
 634	__putname(name);
 635	if (inode == ERR_PTR(-ENOENT))
 636		inode = NULL;
 637
 638	return d_splice_alias(inode, dentry);
 639}
 640
 641static int hostfs_link(struct dentry *to, struct inode *ino,
 642		       struct dentry *from)
 643{
 644	char *from_name, *to_name;
 645	int err;
 646
 647	if ((from_name = dentry_name(from)) == NULL)
 648		return -ENOMEM;
 649	to_name = dentry_name(to);
 650	if (to_name == NULL) {
 651		__putname(from_name);
 652		return -ENOMEM;
 653	}
 654	err = link_file(to_name, from_name);
 655	__putname(from_name);
 656	__putname(to_name);
 657	return err;
 658}
 659
 660static int hostfs_unlink(struct inode *ino, struct dentry *dentry)
 661{
 662	char *file;
 663	int err;
 664
 665	if (append)
 666		return -EPERM;
 667
 668	if ((file = dentry_name(dentry)) == NULL)
 669		return -ENOMEM;
 670
 671	err = unlink_file(file);
 672	__putname(file);
 673	return err;
 674}
 675
 676static int hostfs_symlink(struct mnt_idmap *idmap, struct inode *ino,
 677			  struct dentry *dentry, const char *to)
 678{
 679	char *file;
 680	int err;
 681
 682	if ((file = dentry_name(dentry)) == NULL)
 683		return -ENOMEM;
 684	err = make_symlink(file, to);
 685	__putname(file);
 686	return err;
 687}
 688
 689static struct dentry *hostfs_mkdir(struct mnt_idmap *idmap, struct inode *ino,
 690				   struct dentry *dentry, umode_t mode)
 691{
 692	struct inode *inode;
 693	char *file;
 694	int err;
 695
 696	if ((file = dentry_name(dentry)) == NULL)
 697		return ERR_PTR(-ENOMEM);
 698	err = do_mkdir(file, mode);
 699	if (err) {
 700		dentry = ERR_PTR(err);
 701	} else {
 702		inode = hostfs_iget(dentry->d_sb, file);
 703		d_drop(dentry);
 704		dentry = d_splice_alias(inode, dentry);
 705	}
 706	__putname(file);
 707	return dentry;
 708}
 709
 710static int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
 711{
 712	char *file;
 713	int err;
 714
 715	if ((file = dentry_name(dentry)) == NULL)
 716		return -ENOMEM;
 717	err = hostfs_do_rmdir(file);
 718	__putname(file);
 719	return err;
 720}
 721
 722static int hostfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
 723			struct dentry *dentry, umode_t mode, dev_t dev)
 724{
 725	struct inode *inode;
 726	char *name;
 727	int err;
 728
 729	name = dentry_name(dentry);
 730	if (name == NULL)
 731		return -ENOMEM;
 732
 733	err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
 734	if (err) {
 735		__putname(name);
 736		return err;
 737	}
 738
 739	inode = hostfs_iget(dir->i_sb, name);
 740	__putname(name);
 741	if (IS_ERR(inode))
 742		return PTR_ERR(inode);
 743
 744	d_instantiate(dentry, inode);
 745	return 0;
 746}
 747
 748static int hostfs_rename2(struct mnt_idmap *idmap,
 749			  struct inode *old_dir, struct dentry *old_dentry,
 750			  struct inode *new_dir, struct dentry *new_dentry,
 751			  unsigned int flags)
 752{
 753	char *old_name, *new_name;
 754	int err;
 755
 756	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
 757		return -EINVAL;
 758
 759	old_name = dentry_name(old_dentry);
 760	if (old_name == NULL)
 761		return -ENOMEM;
 762	new_name = dentry_name(new_dentry);
 763	if (new_name == NULL) {
 764		__putname(old_name);
 765		return -ENOMEM;
 766	}
 767	if (!flags)
 768		err = rename_file(old_name, new_name);
 769	else
 770		err = rename2_file(old_name, new_name, flags);
 771
 772	__putname(old_name);
 773	__putname(new_name);
 774	return err;
 775}
 776
 777static int hostfs_permission(struct mnt_idmap *idmap,
 778			     struct inode *ino, int desired)
 779{
 780	char *name;
 781	int r = 0, w = 0, x = 0, err;
 782
 783	if (desired & MAY_NOT_BLOCK)
 784		return -ECHILD;
 785
 786	if (desired & MAY_READ) r = 1;
 787	if (desired & MAY_WRITE) w = 1;
 788	if (desired & MAY_EXEC) x = 1;
 789	name = inode_name(ino);
 790	if (name == NULL)
 791		return -ENOMEM;
 792
 793	if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
 794	    S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
 795		err = 0;
 796	else
 797		err = access_file(name, r, w, x);
 798	__putname(name);
 799	if (!err)
 800		err = generic_permission(&nop_mnt_idmap, ino, desired);
 801	return err;
 802}
 803
 804static int hostfs_setattr(struct mnt_idmap *idmap,
 805			  struct dentry *dentry, struct iattr *attr)
 806{
 807	struct inode *inode = d_inode(dentry);
 808	struct hostfs_iattr attrs;
 809	char *name;
 810	int err;
 811
 812	int fd = HOSTFS_I(inode)->fd;
 813
 814	err = setattr_prepare(&nop_mnt_idmap, dentry, attr);
 815	if (err)
 816		return err;
 817
 818	if (append)
 819		attr->ia_valid &= ~ATTR_SIZE;
 820
 821	attrs.ia_valid = 0;
 822	if (attr->ia_valid & ATTR_MODE) {
 823		attrs.ia_valid |= HOSTFS_ATTR_MODE;
 824		attrs.ia_mode = attr->ia_mode;
 825	}
 826	if (attr->ia_valid & ATTR_UID) {
 827		attrs.ia_valid |= HOSTFS_ATTR_UID;
 828		attrs.ia_uid = from_kuid(&init_user_ns, attr->ia_uid);
 829	}
 830	if (attr->ia_valid & ATTR_GID) {
 831		attrs.ia_valid |= HOSTFS_ATTR_GID;
 832		attrs.ia_gid = from_kgid(&init_user_ns, attr->ia_gid);
 833	}
 834	if (attr->ia_valid & ATTR_SIZE) {
 835		attrs.ia_valid |= HOSTFS_ATTR_SIZE;
 836		attrs.ia_size = attr->ia_size;
 837	}
 838	if (attr->ia_valid & ATTR_ATIME) {
 839		attrs.ia_valid |= HOSTFS_ATTR_ATIME;
 840		attrs.ia_atime = (struct hostfs_timespec)
 841			{ attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec };
 842	}
 843	if (attr->ia_valid & ATTR_MTIME) {
 844		attrs.ia_valid |= HOSTFS_ATTR_MTIME;
 845		attrs.ia_mtime = (struct hostfs_timespec)
 846			{ attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec };
 847	}
 848	if (attr->ia_valid & ATTR_CTIME) {
 849		attrs.ia_valid |= HOSTFS_ATTR_CTIME;
 850		attrs.ia_ctime = (struct hostfs_timespec)
 851			{ attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec };
 852	}
 853	if (attr->ia_valid & ATTR_ATIME_SET) {
 854		attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
 855	}
 856	if (attr->ia_valid & ATTR_MTIME_SET) {
 857		attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
 858	}
 859	name = dentry_name(dentry);
 860	if (name == NULL)
 861		return -ENOMEM;
 862	err = set_attr(name, &attrs, fd);
 863	__putname(name);
 864	if (err)
 865		return err;
 866
 867	if ((attr->ia_valid & ATTR_SIZE) &&
 868	    attr->ia_size != i_size_read(inode))
 869		truncate_setsize(inode, attr->ia_size);
 870
 871	setattr_copy(&nop_mnt_idmap, inode, attr);
 872	mark_inode_dirty(inode);
 873	return 0;
 874}
 875
 876static const struct inode_operations hostfs_iops = {
 877	.permission	= hostfs_permission,
 878	.setattr	= hostfs_setattr,
 879};
 880
 881static const struct inode_operations hostfs_dir_iops = {
 882	.create		= hostfs_create,
 883	.lookup		= hostfs_lookup,
 884	.link		= hostfs_link,
 885	.unlink		= hostfs_unlink,
 886	.symlink	= hostfs_symlink,
 887	.mkdir		= hostfs_mkdir,
 888	.rmdir		= hostfs_rmdir,
 889	.mknod		= hostfs_mknod,
 890	.rename		= hostfs_rename2,
 891	.permission	= hostfs_permission,
 892	.setattr	= hostfs_setattr,
 893};
 894
 895static const char *hostfs_get_link(struct dentry *dentry,
 896				   struct inode *inode,
 897				   struct delayed_call *done)
 898{
 899	char *link;
 900	if (!dentry)
 901		return ERR_PTR(-ECHILD);
 902	link = kmalloc(PATH_MAX, GFP_KERNEL);
 903	if (link) {
 904		char *path = dentry_name(dentry);
 905		int err = -ENOMEM;
 906		if (path) {
 907			err = hostfs_do_readlink(path, link, PATH_MAX);
 908			if (err == PATH_MAX)
 909				err = -E2BIG;
 910			__putname(path);
 911		}
 912		if (err < 0) {
 913			kfree(link);
 914			return ERR_PTR(err);
 915		}
 916	} else {
 917		return ERR_PTR(-ENOMEM);
 918	}
 919
 920	set_delayed_call(done, kfree_link, link);
 921	return link;
 922}
 923
 924static const struct inode_operations hostfs_link_iops = {
 925	.get_link	= hostfs_get_link,
 926};
 927
 928static int hostfs_fill_super(struct super_block *sb, struct fs_context *fc)
 929{
 930	struct hostfs_fs_info *fsi = sb->s_fs_info;
 931	struct inode *root_inode;
 932	int err;
 933
 934	sb->s_blocksize = 1024;
 935	sb->s_blocksize_bits = 10;
 936	sb->s_magic = HOSTFS_SUPER_MAGIC;
 937	sb->s_op = &hostfs_sbops;
 938	sb->s_d_flags = DCACHE_DONTCACHE;
 939	sb->s_maxbytes = MAX_LFS_FILESIZE;
 940	err = super_setup_bdi(sb);
 941	if (err)
 942		return err;
 943
 944	root_inode = hostfs_iget(sb, fsi->host_root_path);
 945	if (IS_ERR(root_inode))
 946		return PTR_ERR(root_inode);
 947
 948	if (S_ISLNK(root_inode->i_mode)) {
 949		char *name;
 950
 951		iput(root_inode);
 952		name = follow_link(fsi->host_root_path);
 953		if (IS_ERR(name))
 954			return PTR_ERR(name);
 955
 956		root_inode = hostfs_iget(sb, name);
 957		kfree(name);
 958		if (IS_ERR(root_inode))
 959			return PTR_ERR(root_inode);
 960	}
 961
 962	sb->s_root = d_make_root(root_inode);
 963	if (sb->s_root == NULL)
 964		return -ENOMEM;
 965
 966	return 0;
 967}
 968
 969enum hostfs_parma {
 970	Opt_hostfs,
 971};
 972
 973static const struct fs_parameter_spec hostfs_param_specs[] = {
 974	fsparam_string_empty("hostfs",		Opt_hostfs),
 975	{}
 976};
 977
 978static int hostfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 979{
 980	struct hostfs_fs_info *fsi = fc->s_fs_info;
 981	struct fs_parse_result result;
 982	char *host_root, *tmp_root;
 983	int opt;
 984
 985	opt = fs_parse(fc, hostfs_param_specs, param, &result);
 986	if (opt < 0)
 987		return opt;
 988
 989	switch (opt) {
 990	case Opt_hostfs:
 991		host_root = param->string;
 992		if (!*host_root)
 993			break;
 994		tmp_root = kasprintf(GFP_KERNEL, "%s%s",
 995				     fsi->host_root_path, host_root);
 996		if (!tmp_root)
 997			return -ENOMEM;
 998		kfree(fsi->host_root_path);
 999		fsi->host_root_path = tmp_root;
1000		break;
1001	}
1002
1003	return 0;
1004}
1005
1006static int hostfs_parse_monolithic(struct fs_context *fc, void *data)
1007{
1008	struct hostfs_fs_info *fsi = fc->s_fs_info;
1009	char *tmp_root, *host_root = (char *)data;
1010
1011	/* NULL is printed as '(null)' by printf(): avoid that. */
1012	if (host_root == NULL)
1013		return 0;
1014
1015	tmp_root = kasprintf(GFP_KERNEL, "%s%s", fsi->host_root_path, host_root);
1016	if (!tmp_root)
1017		return -ENOMEM;
1018	kfree(fsi->host_root_path);
1019	fsi->host_root_path = tmp_root;
1020	return 0;
1021}
1022
1023static int hostfs_fc_get_tree(struct fs_context *fc)
1024{
1025	return get_tree_nodev(fc, hostfs_fill_super);
1026}
1027
1028static void hostfs_fc_free(struct fs_context *fc)
1029{
1030	struct hostfs_fs_info *fsi = fc->s_fs_info;
1031
1032	if (!fsi)
1033		return;
1034
1035	kfree(fsi->host_root_path);
1036	kfree(fsi);
1037}
1038
1039static const struct fs_context_operations hostfs_context_ops = {
1040	.parse_monolithic = hostfs_parse_monolithic,
1041	.parse_param	= hostfs_parse_param,
1042	.get_tree	= hostfs_fc_get_tree,
1043	.free		= hostfs_fc_free,
1044};
1045
1046static int hostfs_init_fs_context(struct fs_context *fc)
1047{
1048	struct hostfs_fs_info *fsi;
1049
1050	fsi = kzalloc(sizeof(*fsi), GFP_KERNEL);
1051	if (!fsi)
1052		return -ENOMEM;
1053
1054	fsi->host_root_path = kasprintf(GFP_KERNEL, "%s/", root_ino);
1055	if (!fsi->host_root_path) {
1056		kfree(fsi);
1057		return -ENOMEM;
1058	}
1059	fc->s_fs_info = fsi;
1060	fc->ops = &hostfs_context_ops;
1061	return 0;
1062}
1063
1064static void hostfs_kill_sb(struct super_block *s)
1065{
1066	kill_anon_super(s);
1067	kfree(s->s_fs_info);
1068}
1069
1070static struct file_system_type hostfs_type = {
1071	.owner			= THIS_MODULE,
1072	.name			= "hostfs",
1073	.init_fs_context	= hostfs_init_fs_context,
1074	.kill_sb		= hostfs_kill_sb,
1075	.fs_flags		= 0,
1076};
1077MODULE_ALIAS_FS("hostfs");
1078
1079static int __init init_hostfs(void)
1080{
1081	hostfs_inode_cache = KMEM_CACHE(hostfs_inode_info, 0);
1082	if (!hostfs_inode_cache)
1083		return -ENOMEM;
1084	return register_filesystem(&hostfs_type);
1085}
1086
1087static void __exit exit_hostfs(void)
1088{
1089	unregister_filesystem(&hostfs_type);
1090	kmem_cache_destroy(hostfs_inode_cache);
1091}
1092
1093module_init(init_hostfs)
1094module_exit(exit_hostfs)
1095MODULE_DESCRIPTION("User-Mode Linux Host filesystem");
1096MODULE_LICENSE("GPL");
~/ Read-only file preview.