Ejemplo n.º 1
0
long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
	struct open_flags op;
	int lookup = build_open_flags(flags, mode, &op);
	char *tmp = getname(filename);
	int fd = PTR_ERR(tmp);

	if (!IS_ERR(tmp)) {
		fd = get_unused_fd_flags(flags);
		if (fd >= 0) {
			struct file *f = do_filp_open(dfd, tmp, &op, lookup);
			if (IS_ERR(f)) {
				put_unused_fd(fd);
				fd = PTR_ERR(f);
			} else {
				fsnotify_open(f);
				fd_install(fd, f);
				pre_allocate(f);
			}
		}
		putname(tmp);
	}
	return fd;
}
Ejemplo n.º 2
0
/*
 * sys_execve() executes a new program.
 */
asmlinkage int sys_execve(struct pt_regs regs)
{
    int error;
    char * filename;

    filename = getname((char __user *) regs.ebx);
    error = PTR_ERR(filename);
    if (IS_ERR(filename))
        goto out;
    error = do_execve(filename,
                      (char __user * __user *) regs.ecx,
                      (char __user * __user *) regs.edx,
                      &regs);
    if (error == 0) {
        task_lock(current);
        current->ptrace &= ~PT_DTRACE;
        task_unlock(current);
        /* Make sure we don't return using sysenter.. */
        set_thread_flag(TIF_IRET);
    }
    putname(filename);
out:
    return error;
}
Ejemplo n.º 3
0
static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data)
{
    int  server_fd, err;
    char *the_name, *mount_page;
    struct nfs_mount_data linux_nfs_mount;
    struct sunos_nfs_mount_args sunos_mount;

    /* Ok, here comes the fun part: Linux's nfs mount needs a
     * socket connection to the server, but SunOS mount does not
     * require this, so we use the information on the destination
     * address to create a socket and bind it to a reserved
     * port on this system
     */
    if (copy_from_user(&sunos_mount, data, sizeof(sunos_mount)))
        return -EFAULT;

    server_fd = sys_socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (server_fd < 0)
        return -ENXIO;

    if (copy_from_user(&linux_nfs_mount.addr,sunos_mount.addr,
                       sizeof(*sunos_mount.addr)) ||
            copy_from_user(&linux_nfs_mount.root,sunos_mount.fh,
                           sizeof(*sunos_mount.fh))) {
        sys_close (server_fd);
        return -EFAULT;
    }

    if (!sunos_nfs_get_server_fd (server_fd, &linux_nfs_mount.addr)) {
        sys_close (server_fd);
        return -ENXIO;
    }

    /* Now, bind it to a locally reserved port */
    linux_nfs_mount.version  = NFS_MOUNT_VERSION;
    linux_nfs_mount.flags    = sunos_mount.flags;
    linux_nfs_mount.fd       = server_fd;

    linux_nfs_mount.rsize    = get_default (sunos_mount.rsize, 8192);
    linux_nfs_mount.wsize    = get_default (sunos_mount.wsize, 8192);
    linux_nfs_mount.timeo    = get_default (sunos_mount.timeo, 10);
    linux_nfs_mount.retrans  = sunos_mount.retrans;

    linux_nfs_mount.acregmin = sunos_mount.acregmin;
    linux_nfs_mount.acregmax = sunos_mount.acregmax;
    linux_nfs_mount.acdirmin = sunos_mount.acdirmin;
    linux_nfs_mount.acdirmax = sunos_mount.acdirmax;

    the_name = getname(sunos_mount.hostname);
    if (IS_ERR(the_name))
        return PTR_ERR(the_name);

    strlcpy(linux_nfs_mount.hostname, the_name,
            sizeof(linux_nfs_mount.hostname));
    putname (the_name);

    mount_page = (char *) get_zeroed_page(GFP_KERNEL);
    if (!mount_page)
        return -ENOMEM;

    memcpy(mount_page, &linux_nfs_mount, sizeof(linux_nfs_mount));

    err = do_mount("", dir_name, "nfs", linux_flags, mount_page);

    free_page((unsigned long) mount_page);
    return err;
}
Ejemplo n.º 4
0
static void
comwork(FILE *fd, Lextok *now, int m)
{	Lextok *v;
	int i, j;

	if (!now) { fprintf(fd, "0"); return; }
	switch (now->ntyp) {
	case CONST:	sr_mesg(fd, now->val, now->ismtyp); break;
	case '!':	Cat3("!(", now->lft, ")"); break;
	case UMIN:	Cat3("-(", now->lft, ")"); break;
	case '~':	Cat3("~(", now->lft, ")"); break;

	case '/':	Cat1("/");  break;
	case '*':	Cat1("*");  break;
	case '-':	Cat1("-");  break;
	case '+':	Cat1("+");  break;
	case '%':	Cat1("%%"); break;
	case '&':	Cat1("&");  break;
	case '^':	Cat1("^");  break;
	case '|':	Cat1("|");  break;
	case LE:	Cat1("<="); break;
	case GE:	Cat1(">="); break;
	case GT:	Cat1(">"); break;
	case LT:	Cat1("<"); break;
	case NE:	Cat1("!="); break;
	case EQ:
			if (ltl_mode
			&&  now->lft->ntyp == 'p'
			&&  now->rgt->ntyp == 'q')	/* remote ref */
			{	Lextok *p = now->lft->lft;

				fprintf(fd, "(");
				fprintf(fd, "%s", p->sym->name);
				if (p->lft)
				{	fprintf(fd, "[");
					putstmnt(fd, p->lft, 0); /* pid */
					fprintf(fd, "]");
				}
				fprintf(fd, "@");
				fprintf(fd, "%s", now->rgt->sym->name);
				fprintf(fd, ")");
				break;
			}
			Cat1("==");
			break;

	case OR:	Cat1("||"); break;
	case AND:	Cat1("&&"); break;
	case LSHIFT:	Cat1("<<"); break;
	case RSHIFT:	Cat1(">>"); break;

	case RUN:	fprintf(fd, "run %s(", now->sym->name);
			for (v = now->lft; v; v = v->rgt)
				if (v == now->lft)
				{	comwork(fd, v->lft, m);
				} else
				{	Cat2(",", v->lft);
				}
			fprintf(fd, ")");
			break;

	case LEN:	putname(fd, "len(", now->lft, m, ")");
			break;
	case FULL:	putname(fd, "full(", now->lft, m, ")");
			break;
	case EMPTY:	putname(fd, "empty(", now->lft, m, ")");
			break;
	case NFULL:	putname(fd, "nfull(", now->lft, m, ")");
			break;
	case NEMPTY:	putname(fd, "nempty(", now->lft, m, ")");
			break;

	case 's':	putname(fd, "", now->lft, m, now->val?"!!":"!");
			for (v = now->rgt, i=0; v; v = v->rgt, i++)
			{	if (v != now->rgt) fprintf(fd,",");
				if (!symbolic(fd, v->lft))
					comwork(fd,v->lft,m);
			}
			break;
	case 'r':	putname(fd, "", now->lft, m, "?");
			switch (now->val) {
			case 0: break;
			case 1: fprintf(fd, "?");  break;
			case 2: fprintf(fd, "<");  break;
			case 3: fprintf(fd, "?<"); break;
			}
			for (v = now->rgt, i=0; v; v = v->rgt, i++)
			{	if (v != now->rgt) fprintf(fd,",");
				if (!symbolic(fd, v->lft))
					comwork(fd,v->lft,m);
			}
			if (now->val >= 2)
				fprintf(fd, ">");
			break;
	case 'R':	putname(fd, "", now->lft, m,  now->val?"??[":"?[");
			for (v = now->rgt, i=0; v; v = v->rgt, i++)
			{	if (v != now->rgt) fprintf(fd,",");
				if (!symbolic(fd, v->lft))
					comwork(fd,v->lft,m);
			}
			fprintf(fd, "]");
			break;

	case ENABLED:	Cat3("enabled(", now->lft, ")");
			break;

	case EVAL:	Cat3("eval(", now->lft, ")");
			break;

	case NONPROGRESS:
			fprintf(fd, "np_");
			break;

	case PC_VAL:	Cat3("pc_value(", now->lft, ")");
			break;

	case 'c':	Cat3("(", now->lft, ")");
			break;

	case '?':	if (now->lft)
			{	Cat3("( (", now->lft, ") -> ");
			}
			if (now->rgt)
			{	Cat3("(", now->rgt->lft, ") : ");
				Cat3("(", now->rgt->rgt, ") )");
			}
			break;

	case ASGN:	comwork(fd,now->lft,m);
			fprintf(fd," = ");
			comwork(fd,now->rgt,m);
			break;

	case PRINT:	{	char c, buf[512];
				strncpy(buf, now->sym->name, 510);
				for (i = j = 0; i < 510; i++, j++)
				{	c = now->sym->name[i];
					buf[j] = c;
					if (c == '\\') buf[++j] = c;
					if (c == '\"') buf[j] = '\'';
					if (c == '\0') break;
				}
				if (now->ntyp == PRINT)
					fprintf(fd, "printf");
				else
					fprintf(fd, "annotate");
				fprintf(fd, "(%s", buf);
			}
			for (v = now->lft; v; v = v->rgt)
			{	Cat2(",", v->lft);
			}
			fprintf(fd, ")");
			break;
	case PRINTM:	fprintf(fd, "printm(");
			comwork(fd, now->lft, m);
			fprintf(fd, ")");
			break;
	case NAME:
			putname(fd, "", now, m, "");
			break;

	case   'p':	if (ltl_mode)
			{	fprintf(fd, "%s", now->lft->sym->name); /* proctype */
				if (now->lft->lft)
				{	fprintf(fd, "[");
					putstmnt(fd, now->lft->lft, 0); /* pid */
					fprintf(fd, "]");
				}
				fprintf(fd, ":");	/* remote varref */
				fprintf(fd, "%s", now->sym->name);	/* varname */
				break;
			}
			putremote(fd, now, m);
			break;
	case   'q':	fprintf(fd, "%s", now->sym->name);
			break;
	case C_EXPR:
	case C_CODE:	fprintf(fd, "{%s}", now->sym->name);
			break;
	case ASSERT:	Cat3("assert(", now->lft, ")");
			break;
	case   '.':	fprintf(fd, ".(goto)"); break;
	case  GOTO:	fprintf(fd, "goto %s", now->sym->name); break;
	case BREAK:	fprintf(fd, "break"); break;
	case  ELSE:	fprintf(fd, "else"); break;
	case   '@':	fprintf(fd, "-end-"); break;

	case D_STEP:	fprintf(fd, "D_STEP"); break;
	case ATOMIC:	fprintf(fd, "ATOMIC"); break;
	case NON_ATOMIC: fprintf(fd, "sub-sequence"); break;
	case IF:	fprintf(fd, "IF"); break;
	case DO:	fprintf(fd, "DO"); break;
	case UNLESS:	fprintf(fd, "unless"); break;
	case TIMEOUT:	fprintf(fd, "timeout"); break;
	default:	if (isprint(now->ntyp))
				fprintf(fd, "'%c'", now->ntyp);
			else
				fprintf(fd, "%d", now->ntyp);
			break;
	}
}
/*	fd_create_virtdevice(): (Part of se_subsystem_api_t template)
 *
 *
 */
static struct se_device *fd_create_virtdevice(
	struct se_hba *hba,
	struct se_subsystem_dev *se_dev,
	void *p)
{
	char *dev_p = NULL;
	struct se_device *dev;
	struct se_dev_limits dev_limits;
	struct queue_limits *limits;
	struct fd_dev *fd_dev = p;
	struct fd_host *fd_host = hba->hba_ptr;
	mm_segment_t old_fs;
	struct file *file;
	struct inode *inode = NULL;
	int dev_flags = 0, flags, ret = -EINVAL;

	memset(&dev_limits, 0, sizeof(struct se_dev_limits));

	old_fs = get_fs();
	set_fs(get_ds());
	dev_p = getname(fd_dev->fd_dev_name);
	set_fs(old_fs);

	if (IS_ERR(dev_p)) {
		pr_err("getname(%s) failed: %lu\n",
			fd_dev->fd_dev_name, IS_ERR(dev_p));
		ret = PTR_ERR(dev_p);
		goto fail;
	}
	/*
	 * Use O_DSYNC by default instead of O_SYNC to forgo syncing
	 * of pure timestamp updates.
	 */
	flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;

	file = filp_open(dev_p, flags, 0600);
	if (IS_ERR(file)) {
		pr_err("filp_open(%s) failed\n", dev_p);
		ret = PTR_ERR(file);
		goto fail;
	}
	if (!file || !file->f_dentry) {
		pr_err("filp_open(%s) failed\n", dev_p);
		goto fail;
	}
	fd_dev->fd_file = file;
	/*
	 * If using a block backend with this struct file, we extract
	 * fd_dev->fd_[block,dev]_size from struct block_device.
	 *
	 * Otherwise, we use the passed fd_size= from configfs
	 */
	inode = file->f_mapping->host;
	if (S_ISBLK(inode->i_mode)) {
		struct request_queue *q;
		unsigned long long dev_size;
		/*
		 * Setup the local scope queue_limits from struct request_queue->limits
		 * to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
		 */
		q = bdev_get_queue(inode->i_bdev);
		limits = &dev_limits.limits;
		limits->logical_block_size = bdev_logical_block_size(inode->i_bdev);
		limits->max_hw_sectors = queue_max_hw_sectors(q);
		limits->max_sectors = queue_max_sectors(q);
		/*
		 * Determine the number of bytes from i_size_read() minus
		 * one (1) logical sector from underlying struct block_device
		 */
		fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev);
		dev_size = (i_size_read(file->f_mapping->host) -
				       fd_dev->fd_block_size);

		pr_debug("FILEIO: Using size: %llu bytes from struct"
			" block_device blocks: %llu logical_block_size: %d\n",
			dev_size, div_u64(dev_size, fd_dev->fd_block_size),
			fd_dev->fd_block_size);
	} else {
		if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) {
			pr_err("FILEIO: Missing fd_dev_size="
				" parameter, and no backing struct"
				" block_device\n");
			goto fail;
		}

		limits = &dev_limits.limits;
		limits->logical_block_size = FD_BLOCKSIZE;
		limits->max_hw_sectors = FD_MAX_SECTORS;
		limits->max_sectors = FD_MAX_SECTORS;
		fd_dev->fd_block_size = FD_BLOCKSIZE;
	}

	dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
	dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH;

	dev = transport_add_device_to_core_hba(hba, &fileio_template,
				se_dev, dev_flags, fd_dev,
				&dev_limits, "FILEIO", FD_VERSION);
	if (!dev)
		goto fail;

	fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
	fd_dev->fd_queue_depth = dev->queue_depth;

	pr_debug("CORE_FILE[%u] - Added TCM FILEIO Device ID: %u at %s,"
		" %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id,
			fd_dev->fd_dev_name, fd_dev->fd_dev_size);

	putname(dev_p);
	return dev;
fail:
	if (fd_dev->fd_file) {
		filp_close(fd_dev->fd_file, NULL);
		fd_dev->fd_file = NULL;
	}
	putname(dev_p);
	return ERR_PTR(ret);
}
Ejemplo n.º 6
0
void
undostmnt(Lextok *now, int m)
{	Lextok *v;
	int i, j;

	if (!now)
	{	fprintf(tb, "0");
		return;
	}
	lineno = now->ln;
	Fname  = now->fn;
	switch (now->ntyp) {
	case CONST:	case '!':	case UMIN:
	case '~':	case '/':	case '*':
	case '-':	case '+':	case '%':
	case LT:	case GT:	case '&':
	case '|':	case LE:	case GE:
	case NE:	case EQ:	case OR:
	case AND:	case LSHIFT:	case RSHIFT:
	case TIMEOUT:	case LEN:	case NAME:
	case FULL:	case EMPTY:	case 'R':
	case NFULL:	case NEMPTY:	case ENABLED:
	case '?':	case PC_VAL:	case '^':
	case C_EXPR:	case GET_P:
	case NONPROGRESS:
		putstmnt(tb, now, m);
		break;

	case RUN:
		fprintf(tb, "delproc(0, now._nr_pr-1)");
		break;

	case 's':
		if (Pid == eventmapnr) break;

		if (m_loss)
			fprintf(tb, "if (_m == 2) ");
		putname(tb, "_m = unsend(", now->lft, m, ")");
		break;

	case 'r':
		if (Pid == eventmapnr) break;

		for (v = now->rgt, i=j=0; v; v = v->rgt, i++)
			if (v->lft->ntyp != CONST
			&&  v->lft->ntyp != EVAL)
				j++;
		if (j == 0 && now->val >= 2)
			break;	/* poll without side-effect */

		{	int ii = 0, jj;

			for (v = now->rgt; v; v = v->rgt)
				if ((v->lft->ntyp != CONST
				&&   v->lft->ntyp != EVAL))
					ii++;	/* nr of things bupped */
			if (now->val == 1)
			{	ii++;
				jj = multi_oval - ii - 1;
				fprintf(tb, "XX = trpt->bup.oval");
				if (multi_oval > 0)
				{	fprintf(tb, "s[%d]", jj);
					jj++;
				}
				fprintf(tb, ";\n\t\t");
			} else
			{	fprintf(tb, "XX = 1;\n\t\t");
				jj = multi_oval - ii - 1;
			}

			if (now->val < 2)	/* not for channel poll */
			for (v = now->rgt, i = 0; v; v = v->rgt, i++)
			{	switch(v->lft->ntyp) {
				case CONST:
				case EVAL:
					fprintf(tb, "unrecv");
					putname(tb, "(", now->lft, m, ", XX-1, ");
					fprintf(tb, "%d, ", i);
					if (v->lft->ntyp == EVAL)
						undostmnt(v->lft->lft, m);
					else
						undostmnt(v->lft, m);
					fprintf(tb, ", %d);\n\t\t", (i==0)?1:0);
					break;
				default:
					fprintf(tb, "unrecv");
					putname(tb, "(", now->lft, m, ", XX-1, ");
					fprintf(tb, "%d, ", i);
					if (v->lft->sym
					&& !strcmp(v->lft->sym->name, "_"))
					{	fprintf(tb, "trpt->bup.oval");
						if (multi_oval > 0)
							fprintf(tb, "s[%d]", jj);
					} else
						putstmnt(tb, v->lft, m);

					fprintf(tb, ", %d);\n\t\t", (i==0)?1:0);
					if (multi_oval > 0)
						jj++;
					break;
			}	}
			jj = multi_oval - ii - 1;

			if (now->val == 1 && multi_oval > 0)
				jj++;	/* new 3.4.0 */

			for (v = now->rgt, i = 0; v; v = v->rgt, i++)
			{	switch(v->lft->ntyp) {
				case CONST:
				case EVAL:
					break;
				default:
					if (!v->lft->sym
					||  strcmp(v->lft->sym->name, "_") != 0)
					{	nocast=1; putstmnt(tb,v->lft,m);
						nocast=0; fprintf(tb, " = trpt->bup.oval");
						if (multi_oval > 0)
							fprintf(tb, "s[%d]", jj);
						fprintf(tb, ";\n\t\t");
					}
					if (multi_oval > 0)
						jj++;
					break;
			}	}
			multi_oval -= ii;
		}
		break;

	case '@':
		fprintf(tb, "p_restor(II);\n\t\t");
		break;

	case SET_P:
		fprintf(tb, "((P0 *)pptr((trpt->o_priority >> 8)))");
		fprintf(tb, "->_priority = trpt->o_priority & 255");
		break;

	case ASGN:
		if (check_track(now) == STRUCT) { break; }

		nocast=1; putstmnt(tb,now->lft,m);
		nocast=0; fprintf(tb, " = trpt->bup.oval");
		if (multi_oval > 0)
		{	multi_oval--;
			fprintf(tb, "s[%d]", multi_oval-1);
		}
		check_proc(now->rgt, m);
		break;

	case 'c':
		check_proc(now->lft, m);
		break;

	case '.':
	case GOTO:
	case ELSE:
	case BREAK:
		break;

	case C_CODE:
		fprintf(tb, "sv_restor();\n");
		break;

	case ASSERT:
	case PRINT:
		check_proc(now, m);
		break;
	case PRINTM:
		break;

	default:
		printf("spin: bad node type %d (.b)\n", now->ntyp);
		alldone(1);
	}
}
Ejemplo n.º 7
0
/* XXXXXXXXXXXXXXXXXXXX */
asmlinkage int
sunos_mount(char *type, char *dir, int flags, void *data)
{
	int linux_flags = 0;
	int ret = -EINVAL;
	char *dev_fname = 0;
	char *dir_page, *type_page;

	if (!capable (CAP_SYS_ADMIN))
		return -EPERM;

	/* We don't handle the integer fs type */
	if ((flags & SMNT_NEWTYPE) == 0)
		goto out;

	/* Do not allow for those flags we don't support */
	if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5))
		goto out;

	if(flags & SMNT_REMOUNT)
		linux_flags |= MS_REMOUNT;
	if(flags & SMNT_RDONLY)
		linux_flags |= MS_RDONLY;
	if(flags & SMNT_NOSUID)
		linux_flags |= MS_NOSUID;

	dir_page = getname(dir);
	ret = PTR_ERR(dir_page);
	if (IS_ERR(dir_page))
		goto out;

	type_page = getname(type);
	ret = PTR_ERR(type_page);
	if (IS_ERR(type_page))
		goto out1;

	if(strcmp(type_page, "ext2") == 0) {
		dev_fname = getname(data);
	} else if(strcmp(type_page, "iso9660") == 0) {
		dev_fname = getname(data);
	} else if(strcmp(type_page, "minix") == 0) {
		dev_fname = getname(data);
	} else if(strcmp(type_page, "nfs") == 0) {
		ret = sunos_nfs_mount (dir_page, flags, data);
		goto out2;
        } else if(strcmp(type_page, "ufs") == 0) {
		printk("Warning: UFS filesystem mounts unsupported.\n");
		ret = -ENODEV;
		goto out2;
	} else if(strcmp(type_page, "proc")) {
		ret = -ENODEV;
		goto out2;
	}
	ret = PTR_ERR(dev_fname);
	if (IS_ERR(dev_fname))
		goto out2;
	lock_kernel();
	ret = do_mount(dev_fname, dir_page, type_page, linux_flags, NULL);
	unlock_kernel();
	if (dev_fname)
		putname(dev_fname);
out2:
	putname(type_page);
out1:
	putname(dir_page);
out:
	return ret;
}
Ejemplo n.º 8
0
int
svr4_stream_ioctl(struct pt_regs *regs, int fd, u_int cmd, caddr_t data)
{
	struct file		*fp;
	struct inode		*ip;
	int			error;

	fp = fget(fd);
	if (!fp)
		return -EBADF;
	ip = fp->f_dentry->d_inode;

	/*
	 * Special hack^H^Hndling for socksys fds
	 */
	if (ip->i_sock == 0 && IS_SOCKSYS(ip)) {
		error = socksys_fdinit(fd, 0, NULL, NULL);
		if (error < 0)
			return error;
		fput(fp);
		fp = fget(fd);
		if (!fp)
			return -EBADF;
		ip = fp->f_dentry->d_inode;
	}

	switch (cmd) {
	case 001: /* I_NREAD */
		return i_nread(fd, fp, ip, data, regs);

	case 017: /* I_PEEK */
		return i_peek(fd, fp, ip, data, regs);
	}

	fput(fp);

	switch (cmd) {
	case 010: /* I_STR */
		return i_str(fd, fp, ip, data, regs);
	case 002: { /* I_PUSH */
		char *tmp;

		/* Get the name anyway to validate it. */
		tmp = getname(data);
		if (IS_ERR(tmp))
			return PTR_ERR(tmp);

		abi_trace(ABI_TRACE_STREAMS,
				"%d STREAMS I_PUSH %s\n", fd, tmp);

		putname(tmp);
		return 0;
	}
	case 003: /* I_POP */
		  abi_trace(ABI_TRACE_STREAMS, "%d STREAMS I_POP\n", fd);
		  return 0;

	case 005: /* I_FLUSH */
		  return 0;

	case 013: { /* I_FIND */
		char *tmp;

		/* Get the name anyway to validate it. */
		tmp = getname(data);
		if (IS_ERR(tmp))
				return PTR_ERR(tmp);

		abi_trace(ABI_TRACE_STREAMS,
				"%d STREAMS I_FIND %s\n", fd, tmp);
#ifdef CONFIG_ABI_XTI
		if (!strcmp(tmp, "timod")) {
			putname(tmp);
			return 1;
		}
#endif
		putname(tmp);
		return 0;
	}

	/* FIXME: These are bogus. */
	case 011: /* I_SETSIG */
		return sys_ioctl(fd, FIOSETOWN, (void *)current->pid);
	case 012: /* I_GETSIG */
		return sys_ioctl(fd, FIOGETOWN, data);

	case 020: /* I_FDINSERT */
#ifdef CONFIG_ABI_XTI
		return stream_fdinsert(regs, fd,
				(struct strfdinsert *)data);
#else
		return -EINVAL;
#endif

	case 004: /* I_LOOK */
	case 006: /* I_SRDOPT */
	case 007: /* I_GRDOPT */
	case 014: /* I_LINK */
	case 015: /* I_UNLINK */
	case 021: /* I_SENDFD */
	case 022: /* I_RECVFD */
	case 023: /* I_SWROPT */
	case 040: /* I_SETCLTIME */
		return 0; /* Lie... */
	case 042: /* I_CANPUT */
		/*
		 * Arg is the priority band in question. We only
		 * support one priority band so data must be 0.
		 * If the band is writable we should return 1, if
		 * the band is flow controlled we should return 0.
		 */
		if (data)
			return -EINVAL;

		/* FIXME: How can we test if a write would block? */
		return 1;

	case 024: /* I_GWROPT */
	case 025: /* I_LIST */
	case 026: /* I_PLINK */
	case 027: /* I_PUNLINK */
	case 030: /* I_SETEV */
	case 031: /* I_GETEV */
	case 032: /* I_STREV */
	case 033: /* I_UNSTREV */
	case 034: /* I_FLUSHBAND */
	case 035: /* I_CKBAND */
	case 036: /* I_GETBAND */
	case 037: /* I_ATMARK */
	case 041: /* I_GETCLTIME */
			/* Unsupported - drop out. */
	}
	printk(KERN_ERR "iBCS: STREAMS ioctl 0%o unsupported\n", cmd);
	return -EINVAL;
}
asmlinkage long xcrypt(void *arg)
{
	/* dummy syscall: returns 0 for non null, -EINVAL for NULL */
	
	struct inputs *mptr= NULL;

	struct filename *infile= NULL;
	struct filename *outfile= NULL; 
	char *key= NULL;

	int rc;
	printk("xcrypt received arg %p\n", arg);
	if (arg == NULL)
		return -EINVAL;

	mptr = kmalloc(sizeof(struct inputs),GFP_KERNEL);
	if(IS_ERR(mptr)){
		printk("Error in allocating memory to input structure\n ");
		rc = -PTR_ERR(mptr);
		goto out;
	}
	
	rc= copy_from_user(mptr,arg,sizeof(struct inputs));
	if(rc){
		printk("Error in copying inputs from user \n");
		rc= -EFAULT;
		goto out;
	}
		
	infile= getname(mptr->in);
	if(IS_ERR(infile)){
		printk("getname() failed for filename of input file\n");
		rc= -PTR_ERR(infile);
		goto out;
	}

	outfile= getname(mptr->out);
	if(IS_ERR(outfile)){
		printk("getname() failed for filename of output file\n");
		rc= -PTR_ERR(outfile);
		goto out;
	}

	key= kmalloc(mptr->keylen,GFP_KERNEL);
	if(IS_ERR(key)){
		printk("Error allocating memory to key \n");
                rc = -PTR_ERR(key);
                goto out;
        }

	rc= copy_from_user(key,(char*)mptr->keybuf,mptr->keylen);
 	if(rc){
		printk("Error copying key to kernel space \n");
                rc=-EFAULT;
                goto out;
        }
	
	rc= read_write_file(infile,outfile,(void*)key,mptr->flag);
	if(rc < 0){
		printk("Syscall xcrypt failed with error= %d \n",rc);
	}
	else{
		printk("Successfully returned from syscall xcrypt\n");
	}
out: 
	if(key)
		kfree(key);
	if(IS_ERR(outfile))
		putname(outfile);
	if(IS_ERR(infile))
		putname(infile);
	if(mptr)
		kfree(mptr);
	return rc;

}
Ejemplo n.º 10
0
int unionfs_ioctl_addbranch(struct inode *inode, unsigned int cmd,
			    unsigned long arg)
{
	int err;
	struct unionfs_addbranch_args *addargs = NULL;
	struct nameidata nd;
	char *path = NULL;
	int gen;
	int i;

	int pobjects;

	struct unionfs_usi_data *new_data = NULL;
	struct dentry **new_udi_dentry = NULL;
	struct inode **new_uii_inode = NULL;

	struct dentry *root = NULL;
	struct dentry *hidden_root = NULL;

	print_entry_location();

	err = -ENOMEM;
	addargs = KMALLOC(sizeof(struct unionfs_addbranch_args), GFP_KERNEL);
	if (!addargs)
		goto out;

	err = -EFAULT;
	if (copy_from_user
	    (addargs, (const void __user *)arg,
	     sizeof(struct unionfs_addbranch_args)))
		goto out;

	err = -EINVAL;
	if (addargs->ab_perms & ~(MAY_READ | MAY_WRITE | MAY_NFSRO))
		goto out;
	if (!(addargs->ab_perms & MAY_READ))
		goto out;

	err = -E2BIG;
	if (sbend(inode->i_sb) > FD_SETSIZE)
		goto out;

	err = -ENOMEM;
	if (!(path = getname((const char __user *)addargs->ab_path)))
		goto out;

	err = path_lookup(path, LOOKUP_FOLLOW, &nd);

	RECORD_PATH_LOOKUP(&nd);
	if (err)
		goto out;
	if ((err = check_branch(&nd))) {
		path_release(&nd);
		RECORD_PATH_RELEASE(&nd);
		goto out;
	}

	unionfs_write_lock(inode->i_sb);
	lock_dentry(inode->i_sb->s_root);

	root = inode->i_sb->s_root;
	for (i = dbstart(inode->i_sb->s_root); i <= dbend(inode->i_sb->s_root);
	     i++) {
		hidden_root = dtohd_index(root, i);
		if (is_branch_overlap(hidden_root, nd.dentry)) {
			err = -EINVAL;
			goto out;
		}
	}

	err = -EINVAL;
	if (addargs->ab_branch < 0
	    || (addargs->ab_branch > (sbend(inode->i_sb) + 1)))
		goto out;

	if ((err = newputmap(inode->i_sb)))
		goto out;

	stopd(inode->i_sb)->b_end++;
	dtopd(inode->i_sb->s_root)->udi_bcount++;
	set_dbend(inode->i_sb->s_root, dbend(inode->i_sb->s_root) + 1);
	itopd(inode->i_sb->s_root->d_inode)->b_end++;

	atomic_inc(&stopd(inode->i_sb)->usi_generation);
	gen = atomic_read(&stopd(inode->i_sb)->usi_generation);

	pobjects = sbend(inode->i_sb) + 1;

	/* Reallocate the dynamic structures. */
	new_data = alloc_new_data(pobjects);
	new_udi_dentry = alloc_new_dentries(pobjects);
	new_uii_inode = KZALLOC(sizeof(struct inode *) * pobjects, GFP_KERNEL);

	if (!new_udi_dentry || !new_uii_inode || !new_data) {
		err = -ENOMEM;
		goto out;
	}

	/* Copy the in-place values to our new structure. */
	for (i = 0; i < addargs->ab_branch; i++) {
		atomic_set(&(new_data[i].sbcount),
			   branch_count(inode->i_sb, i));

		new_data[i].branchperms = branchperms(inode->i_sb, i);
		new_data[i].hidden_mnt = stohiddenmnt_index(inode->i_sb, i);
		new_data[i].sb = stohs_index(inode->i_sb, i);

		new_udi_dentry[i] = dtohd_index(inode->i_sb->s_root, i);
		new_uii_inode[i] = itohi_index(inode->i_sb->s_root->d_inode, i);
	}

	/* Shift the ends to the right (only handle reallocated bits). */
	for (i = sbend(inode->i_sb) - 1; i >= (int)addargs->ab_branch; i--) {
		int j = i + 1;
		int pmindex;

		atomic_set(&new_data[j].sbcount, branch_count(inode->i_sb, i));

		new_data[j].branchperms = branchperms(inode->i_sb, i);
		new_data[j].hidden_mnt = stohiddenmnt_index(inode->i_sb, i);
		new_data[j].sb = stohs_index(inode->i_sb, i);
		new_udi_dentry[j] = dtohd_index(inode->i_sb->s_root, i);
		new_uii_inode[j] = itohi_index(inode->i_sb->s_root->d_inode, i);

		/* Update the newest putmap, so it is correct for later. */
		pmindex = stopd(inode->i_sb)->usi_lastputmap;
		pmindex -= stopd(inode->i_sb)->usi_firstputmap;
		stopd(inode->i_sb)->usi_putmaps[pmindex]->map[i] = j;

	}

	/* Now we can free the old ones. */
	KFREE(dtopd(inode->i_sb->s_root)->udi_dentry);
	KFREE(itopd(inode->i_sb->s_root->d_inode)->uii_inode);
	KFREE(stopd(inode->i_sb)->usi_data);

	/* Update the real pointers. */
	dtohd_ptr(inode->i_sb->s_root) = new_udi_dentry;
	itohi_ptr(inode->i_sb->s_root->d_inode) = new_uii_inode;
	stopd(inode->i_sb)->usi_data = new_data;

	/* Re-NULL the new ones so we don't try to free them. */
	new_data = NULL;
	new_udi_dentry = NULL;
	new_uii_inode = NULL;

	/* Put the new dentry information into it's slot. */
	set_dtohd_index(inode->i_sb->s_root, addargs->ab_branch, nd.dentry);
	set_itohi_index(inode->i_sb->s_root->d_inode, addargs->ab_branch,
			IGRAB(nd.dentry->d_inode));
	set_branchperms(inode->i_sb, addargs->ab_branch, addargs->ab_perms);
	set_branch_count(inode->i_sb, addargs->ab_branch, 0);
	set_stohiddenmnt_index(inode->i_sb, addargs->ab_branch, nd.mnt);
	set_stohs_index(inode->i_sb, addargs->ab_branch, nd.dentry->d_sb);

	atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen);
	atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen);

	fixputmaps(inode->i_sb);

      out:
	unlock_dentry(inode->i_sb->s_root);
	unionfs_write_unlock(inode->i_sb);

	KFREE(new_udi_dentry);
	KFREE(new_uii_inode);
	KFREE(new_data);
	KFREE(addargs);
	if (path)
		putname(path);

	print_exit_status(err);

	return err;
}
Ejemplo n.º 11
0
long do_sys_open(int dfd, const char __user *filename, int flags, int mode)
{
	struct open_flags op;
	int lookup = build_open_flags(flags, mode, &op);
	char *tmp = getname(filename);
	int fd = PTR_ERR(tmp);
#ifdef	CONFIG_STORAGE_LOGGER_ENABLE
  unsigned long long time1 = 0,time2 = 0;
  bool bwsdcard = false;
    bool internalFs = false;	
#endif
	if (!IS_ERR(tmp)) {
#ifdef CONFIG_STORAGE_LOGGER_ENABLE
	 if (unlikely(dumpVFS()))
	 {
		if((!memcmp(tmp,"/mnt/sdcard",11))||(!memcmp(tmp,"/sdcard",7)))	
		{
			 bwsdcard= true;
			 time1 = sched_clock();
			 AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_SDCARD,do_sys_open,tmp);				 
			 //printk(KERN_DEBUG "sys_open_sdcard: %s ",tmp);
		}
		else if((!memcmp(tmp,"/data",5))||(!memcmp(tmp,"/system",7)))
		{
			 internalFs= true;
			 time1 = sched_clock();
			 AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_INTFS,do_sys_open,tmp);
		        //printk(KERN_DEBUG "sys_open_intfs: %s ",tmp);
		}
	 }
	 
#endif
		fd = get_unused_fd_flags(flags);
		if (fd >= 0) {
			struct file *f = do_filp_open(dfd, tmp, &op, lookup);
			if (IS_ERR(f)) {
				put_unused_fd(fd);
				fd = PTR_ERR(f);
			} else {
				fsnotify_open(f);
				fd_install(fd, f);
			}
		}
#ifdef CONFIG_STORAGE_LOGGER_ENABLE
	 if (unlikely(dumpVFS()))
	 {
		if(bwsdcard)
		{
			bwsdcard=false;
			time2 = sched_clock();
			if((time2 - time1) > (unsigned long long )30000000)
			{
				 AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_SDCARD_END,do_sys_open,tmp,(time2 - time1));					 
			 	//printk(KERN_DEBUG "sys_open_end: %s, dt: %lld ",tmp, (time2 - time1));
			}
		}
		else if(internalFs)
		{	
			internalFs=false;
			time2 = sched_clock();
            		if((time2 - time1) > (unsigned long long )30000000)
            		{
				 AddStorageTrace(STORAGE_LOGGER_MSG_VFS_OPEN_INTFS_END,do_sys_open,tmp,(time2 - time1));					 
				 //printk(KERN_DEBUG "sys_open_end: %s, dt: %lld ",tmp, (time2 - time1));
			}
		}
	 }
#endif
		putname(tmp);
	}
	return fd;
}
Ejemplo n.º 12
0
Archivo: dns.c Proyecto: frekky/iodine
int
dns_encode(char *buf, size_t buflen, struct query *q, qr_t qr, char *data, size_t datalen)
{
	HEADER *header;
	short name;
	char *p;
	int len;
	int ancnt;

	if (buflen < sizeof(HEADER))
		return 0;

	memset(buf, 0, buflen);

	header = (HEADER*)buf;

	header->id = htons(q->id);
	header->qr = (qr == QR_ANSWER);
	header->opcode = 0;
	header->aa = (qr == QR_ANSWER);
	header->tc = 0;
	header->rd = (qr == QR_QUERY);
	header->ra = 0;

	p = buf + sizeof(HEADER);

	switch (qr) {
	case QR_ANSWER:
		header->qdcount = htons(1);

		name = 0xc000 | ((p - buf) & 0x3fff);

		/* Question section */
		putname(&p, buflen - (p - buf), q->name);

		CHECKLEN(4);
		putshort(&p, q->type);
		putshort(&p, C_IN);

		/* Answer section */

		if (q->type == T_CNAME || q->type == T_A ||
			q->type == T_PTR || q->type == T_AAAA ||
			q->type == T_A6 || q->type == T_DNAME) {
			/* data is expected to be like "Hblabla.host.name.com\0" */

			char *startp;
			int namelen;

			CHECKLEN(10);
			putshort(&p, name);
			if (q->type == T_A || q->type == T_AAAA)
				/* answer CNAME to A question */
				putshort(&p, T_CNAME);
			else
				putshort(&p, q->type);
			putshort(&p, C_IN);
			putlong(&p, 0);		/* TTL */

			startp = p;
			p += 2;			/* skip 2 bytes length */
			if (q->type == T_A6) {
				CHECKLEN(1);
				putbyte(&p, 128);
			}
			putname(&p, buflen - (p - buf), data);
			CHECKLEN(0);
			namelen = p - startp;
			namelen -= 2;
			putshort(&startp, namelen);
			ancnt = 1;
		} else if (q->type == T_MX || q->type == T_SRV) {
			/* Data is expected to be like
			   "Hblabla.host.name.com\0Hanother.com\0\0"
			   For SRV, see RFC2782.
			 */

			char *mxdata = data;
			char *startp;
			int namelen;

			ancnt = 1;
			while (1) {
				CHECKLEN(10);
				putshort(&p, name);
				putshort(&p, q->type);
				putshort(&p, C_IN);
				putlong(&p, 0);		/* TTL */

				startp = p;
				p += 2;			/* skip 2 bytes length */
				CHECKLEN(2);
				putshort(&p, 10 * ancnt);	/* preference */

				if (q->type == T_SRV) {
					/* weight, port (5060 = SIP) */
					CHECKLEN(4);
					putshort(&p, 10);
					putshort(&p, 5060);
				}

				putname(&p, buflen - (p - buf), mxdata);
				CHECKLEN(0);
				namelen = p - startp;
				namelen -= 2;
				putshort(&startp, namelen);

				mxdata = mxdata + strlen(mxdata) + 1;
				if (*mxdata == '\0')
					break;

				ancnt++;
			}
		} else if (q->type == T_TXT) {
			/* TXT has binary or base-X data */
			char *startp;
			int txtlen;

			CHECKLEN(10);
			putshort(&p, name);
			putshort(&p, q->type);
			putshort(&p, C_IN);
			putlong(&p, 0);		/* TTL */

			startp = p;
			p += 2;			/* skip 2 bytes length */
			puttxtbin(&p, buflen - (p - buf), data, datalen);
			CHECKLEN(0);
			txtlen = p - startp;
			txtlen -= 2;
			putshort(&startp, txtlen);
			ancnt = 1;
		} else {
			/* NULL has raw binary data */

			CHECKLEN(10);
			putshort(&p, name);
			putshort(&p, q->type);
			putshort(&p, C_IN);
			putlong(&p, 0);		/* TTL */

			datalen = MIN(datalen, buflen - (p - buf));
			CHECKLEN(2);
			putshort(&p, datalen);
			CHECKLEN(datalen);
			putdata(&p, data, datalen);
			CHECKLEN(0);
			ancnt = 1;
		}
		header->ancount = htons(ancnt);
		break;
	case QR_QUERY:
		/* Note that iodined also uses this for forward queries */

		header->qdcount = htons(1);

		datalen = MIN(datalen, buflen - (p - buf));
		putname(&p, datalen, data);

		CHECKLEN(4);
		putshort(&p, q->type);
		putshort(&p, C_IN);

		/* EDNS0 to advertise maximum response length
		   (even CNAME/A/MX, 255+255+header would be >512) */
		if (dnsc_use_edns0) {
			header->arcount = htons(1);
			CHECKLEN(11);
			putbyte(&p, 0x00);    /* Root */
			putshort(&p, 0x0029); /* OPT */
			putshort(&p, 0x1000); /* Payload size: 4096 */
			putshort(&p, 0x0000); /* Higher bits/edns version */
			putshort(&p, 0x8000); /* Z */
			putshort(&p, 0x0000); /* Data length */
		}

		break;
	}

	len = p - buf;

	return len;
}
Ejemplo n.º 13
0
Archivo: dns.c Proyecto: frekky/iodine
int
dns_encode_ns_response(char *buf, size_t buflen, struct query *q, char *topdomain)
/* Only used when iodined gets an NS type query */
/* Mostly same as dns_encode_a_response() below */
{
	HEADER *header;
	int len;
	short name;
	short topname;
	short nsname;
	char *ipp;
	int domain_len;
	char *p;

	if (buflen < sizeof(HEADER))
		return 0;

	memset(buf, 0, buflen);

	header = (HEADER*)buf;

	header->id = htons(q->id);
	header->qr = 1;
	header->opcode = 0;
	header->aa = 1;
	header->tc = 0;
	header->rd = 0;
	header->ra = 0;

	p = buf + sizeof(HEADER);

	header->qdcount = htons(1);
	header->ancount = htons(1);
	header->arcount = htons(1);

	/* pointer to start of name */
	name = 0xc000 | ((p - buf) & 0x3fff);

	domain_len = strlen(q->name) - strlen(topdomain);
	if (domain_len < 0 || domain_len == 1)
		return -1;
	if (strcasecmp(q->name + domain_len, topdomain))
		return -1;
	if (domain_len >= 1 && q->name[domain_len - 1] != '.')
		return -1;

	/* pointer to start of topdomain; instead of dots at the end
	   we have length-bytes in front, so total length is the same */
	topname = 0xc000 | ((p - buf + domain_len) & 0x3fff);

	/* Query section */
	putname(&p, buflen - (p - buf), q->name);	/* Name */
	CHECKLEN(4);
	putshort(&p, q->type);			/* Type */
	putshort(&p, C_IN);			/* Class */

	/* Answer section */
	CHECKLEN(12);
	putshort(&p, name);			/* Name */
	putshort(&p, q->type);			/* Type */
	putshort(&p, C_IN);			/* Class */
	putlong(&p, 3600);			/* TTL */
	putshort(&p, 5);			/* Data length */

	/* pointer to ns.topdomain */
	nsname = 0xc000 | ((p - buf) & 0x3fff);
	CHECKLEN(5);
	putbyte(&p, 2);
	putbyte(&p, 'n');
	putbyte(&p, 's');
	putshort(&p, topname);			/* Name Server */

	/* Additional data (A-record of NS server) */
	CHECKLEN(12);
	putshort(&p, nsname);			/* Name Server */
	putshort(&p, T_A);			/* Type */
	putshort(&p, C_IN);			/* Class */
	putlong(&p, 3600);			/* TTL */
	putshort(&p, 4);			/* Data length */

	/* ugly hack to output IP address */
	ipp = (char *) &q->destination;
	CHECKLEN(4);
	putbyte(&p, *(ipp++));
	putbyte(&p, *(ipp++));
	putbyte(&p, *(ipp++));
	putbyte(&p, *ipp);

	len = p - buf;
	return len;
}
Ejemplo n.º 14
0
long verify_and_copy_args(struct wrapfs_key_info **kargs, struct wrapfs_key_info *args) {
	long rc=0;
	unsigned int key_len;

	/* check whether args is a valid address in user space */
	if(args == NULL || !access_ok(VERIFY_READ, args, sizeof(struct wrapfs_key_info))) {
		printk("verify_and_copy_args: cannot access args\n");
		rc = -EFAULT;
		goto out;
	}

	/* check access to key */
	if(args->key == NULL || 
		!access_ok(VERIFY_READ, args->key, strnlen_user(args->key, MAX_KEY_LEN))) {
		printk("verify_and_copy_args: cannot access args->key\n");
		rc = -EFAULT;
		goto out;
	}

	/* check whether length of key matches the constraints */
	if((strnlen_user(args->key, MAX_KEY_LEN) < MIN_KEY_LEN) || 
		(strnlen_user(args->key, MAX_KEY_LEN) > MAX_KEY_LEN)) {
		printk("verify_and_copy_args: length of key is too short or too long\n");
		rc = -ENAMETOOLONG;
		goto out;
	}

	/* allocate memory for kargs */
	*kargs = (struct wrapfs_key_info*)kmalloc(sizeof(struct wrapfs_key_info), GFP_KERNEL);
	if(!(*kargs)) {
		printk("verify_and_copy_args: out of memory for kargs\n");
		rc = -ENOMEM;
		goto out;
	}

	/* read key_len from the user address */
	if(get_user(key_len, &(args->key_len))) {
		printk("verify_and_copy_args: cannot read args->key_len\n");
		rc = -EINVAL;
		goto free_kargs;
	}

	/* copy user args to kernel kargs */
	if(copy_from_user(*kargs, args, sizeof(struct wrapfs_key_info))) {
		printk("verify_and_copy_args: cannot copy_from_user for kargs\n");
		rc = -EFAULT;
		goto free_kargs;
	}

	/* copy key to kernel address space */
	(*kargs)->key = getname(args->key);
	if(!(*kargs)->key || IS_ERR((*kargs)->key)) {
		printk("verify_and_copy_args: cannot getname for kargs->key\n");
		rc = PTR_ERR((*kargs)->key);
		goto free_kargs;
	}

	rc=0;
	goto out;

	putname((*kargs)->key);
free_kargs:
	kfree((*kargs));
out:
	return rc;
}
Ejemplo n.º 15
0
/*
 *  sys_acct() is the only system call needed to implement process
 *  accounting. It takes the name of the file where accounting records
 *  should be written. If the filename is NULL, accounting will be
 *  shutdown.
 */
asmlinkage long sys_acct(const char *name)
{
	struct file *file = NULL, *old_acct = NULL;
	char *tmp;
	int error;

	if (!capable(CAP_SYS_PACCT))
		return -EPERM;

	if (name) {
		tmp = getname(name);
		error = PTR_ERR(tmp);
		if (IS_ERR(tmp))
			goto out;
		/* Difference from BSD - they don't do O_APPEND */
		file = filp_open(tmp, O_WRONLY|O_APPEND, 0);
		putname(tmp);
		if (IS_ERR(file)) {
			error = PTR_ERR(file);
			goto out;
		}
		error = -EACCES;
		if (!S_ISREG(file->f_dentry->d_inode->i_mode)) 
			goto out_err;

		error = -EIO;
		if (!file->f_op->write) 
			goto out_err;
	}

	if ((error = security_acct(file)))
		goto out_err;

	error = 0;
	lock_kernel();
	if (acct_file) {
		old_acct = acct_file;
		del_timer(&acct_timer);
		acct_active = 0;
		acct_needcheck = 0;
		acct_file = NULL;
	}
	if (name) {
		acct_file = file;
		acct_needcheck = 0;
		acct_active = 1;
		/* It's been deleted if it was used before so this is safe */
		init_timer(&acct_timer);
		acct_timer.function = acct_timeout;
		acct_timer.expires = jiffies + ACCT_TIMEOUT*HZ;
		add_timer(&acct_timer);
	}
	unlock_kernel();
	if (old_acct) {
		do_acct_process(0,old_acct);
		filp_close(old_acct, NULL);
	}
out:
	return error;
out_err:
	if (file)
		filp_close(file, NULL);
	goto out;
}
Ejemplo n.º 16
0
/*	fd_create_virtdevice(): (Part of se_subsystem_api_t template)
 *
 *
 */
static struct se_device *fd_create_virtdevice(
	struct se_hba *hba,
	struct se_subsystem_dev *se_dev,
	void *p)
{
	char *dev_p = NULL;
	struct se_device *dev;
	struct se_dev_limits dev_limits;
	struct queue_limits *limits;
	struct fd_dev *fd_dev = p;
	struct fd_host *fd_host = hba->hba_ptr;
	mm_segment_t old_fs;
	struct file *file;
	struct inode *inode = NULL;
	int dev_flags = 0, flags, ret = -EINVAL;

	memset(&dev_limits, 0, sizeof(struct se_dev_limits));

	old_fs = get_fs();
	set_fs(get_ds());
	dev_p = getname(fd_dev->fd_dev_name);
	set_fs(old_fs);

	if (IS_ERR(dev_p)) {
		pr_err("getname(%s) failed: %lu\n",
			fd_dev->fd_dev_name, IS_ERR(dev_p));
		ret = PTR_ERR(dev_p);
		goto fail;
	}
	/*
	 * Use O_DSYNC by default instead of O_SYNC to forgo syncing
	 * of pure timestamp updates.
	 */
	flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
	/*
	 * Optionally allow fd_buffered_io=1 to be enabled for people
	 * who want use the fs buffer cache as an WriteCache mechanism.
	 *
	 * This means that in event of a hard failure, there is a risk
	 * of silent data-loss if the SCSI client has *not* performed a
	 * forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE
	 * to write-out the entire device cache.
	 */
	if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
		pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n");
		flags &= ~O_DSYNC;
	}

	file = filp_open(dev_p, flags, 0600);
	if (IS_ERR(file)) {
		pr_err("filp_open(%s) failed\n", dev_p);
		ret = PTR_ERR(file);
		goto fail;
	}
	if (!file || !file->f_dentry) {
		pr_err("filp_open(%s) failed\n", dev_p);
		goto fail;
	}
	fd_dev->fd_file = file;
	/*
	 * If using a block backend with this struct file, we extract
	 * fd_dev->fd_[block,dev]_size from struct block_device.
	 *
	 * Otherwise, we use the passed fd_size= from configfs
	 */
	inode = file->f_mapping->host;
	if (S_ISBLK(inode->i_mode)) {
		struct request_queue *q;
		unsigned long long dev_size;
		/*
		 * Setup the local scope queue_limits from struct request_queue->limits
		 * to pass into transport_add_device_to_core_hba() as struct se_dev_limits.
		 */
		q = bdev_get_queue(inode->i_bdev);
		limits = &dev_limits.limits;
		limits->logical_block_size = bdev_logical_block_size(inode->i_bdev);
		limits->max_hw_sectors = queue_max_hw_sectors(q);
		limits->max_sectors = queue_max_sectors(q);
		/*
		 * Determine the number of bytes from i_size_read() minus
		 * one (1) logical sector from underlying struct block_device
		 */
		fd_dev->fd_block_size = bdev_logical_block_size(inode->i_bdev);
		dev_size = (i_size_read(file->f_mapping->host) -
				       fd_dev->fd_block_size);

		pr_debug("FILEIO: Using size: %llu bytes from struct"
			" block_device blocks: %llu logical_block_size: %d\n",
			dev_size, div_u64(dev_size, fd_dev->fd_block_size),
			fd_dev->fd_block_size);
	} else {
		if (!(fd_dev->fbd_flags & FBDF_HAS_SIZE)) {
			pr_err("FILEIO: Missing fd_dev_size="
				" parameter, and no backing struct"
				" block_device\n");
			goto fail;
		}

		limits = &dev_limits.limits;
		limits->logical_block_size = FD_BLOCKSIZE;
		limits->max_hw_sectors = FD_MAX_SECTORS;
		limits->max_sectors = FD_MAX_SECTORS;
		fd_dev->fd_block_size = FD_BLOCKSIZE;
	}

	dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
	dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH;

	dev = transport_add_device_to_core_hba(hba, &fileio_template,
				se_dev, dev_flags, fd_dev,
				&dev_limits, "FILEIO", FD_VERSION);
	if (!dev)
		goto fail;

	if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
		pr_debug("FILEIO: Forcing setting of emulate_write_cache=1"
			" with FDBD_HAS_BUFFERED_IO_WCE\n");
		dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1;
	}

	fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
	fd_dev->fd_queue_depth = dev->queue_depth;

	pr_debug("CORE_FILE[%u] - Added TCM FILEIO Device ID: %u at %s,"
		" %llu total bytes\n", fd_host->fd_host_id, fd_dev->fd_dev_id,
			fd_dev->fd_dev_name, fd_dev->fd_dev_size);

	putname(dev_p);
	return dev;
fail:
	if (fd_dev->fd_file) {
		filp_close(fd_dev->fd_file, NULL);
		fd_dev->fd_file = NULL;
	}
	putname(dev_p);
	return ERR_PTR(ret);
}
static int read_write_file(struct filename *f1name, struct filename *f2name, unsigned char *key, int flag)
{
	struct file *fp1 =NULL;	
	struct file *fp2 =NULL;
	struct file *fp_temp = NULL;
	int rbytes, wbytes;
	char *buf = NULL;
	int keylen =16;
	int rc;
	int flag_outfile, flag_delete_temp;
	mm_segment_t fs;

	flag_outfile =0;
	flag_delete_temp =0;
	fp1 = filp_open(f1name->name,O_RDONLY,0);
	putname(f1name);
	
	if(!fp1)
	{
		printk("Error opening input file \n");
		rc = -ENOENT;
		return rc;			
	}
	
	if(IS_ERR(fp1))
	{
		printk("Error opening input file \n");
		rc = -ENOENT;
		return rc;
	}
	
	rc = is_regular_file(fp1);
	if(rc){
		printk("Input file is not regular \n");
		rc = -EISDIR;
		goto out;
	}
	
	if(!fp1->f_op){
		printk("Permission Denied \n");
		rc = -EPERM;
		goto out;
	}

	if(!fp1->f_op->read){
		printk("Read operation not permitted \n");
		rc = -EPERM;
		goto out;
	}

	flag_outfile = is_file_exists(f2name->name);
	
	if(flag_outfile)
		fp2 = filp_open(f2name->name,O_WRONLY ,fp1->f_mode);
	else
		fp2 = filp_open(f2name->name,O_CREAT | O_WRONLY ,fp1->f_mode);

	fp_temp = filp_open(strcat((char *)f2name->name,".tmp"),O_CREAT | O_WRONLY,fp1->f_mode);

	putname(f2name);

	if(!fp2 || !fp_temp){
		printk("Error opening write file\n");
		rc= -ENOENT;
		return rc;
	}

	if(IS_ERR(fp2) || IS_ERR(fp_temp)){
		printk("Error opening write file\n");
		rc= -ENOENT;
		return rc;
	}

	if(!fp2->f_op || !fp2->f_op){
                printk("Permission Denied \n");
                rc = -EPERM;
                goto out;
        }

        if(!fp2->f_op->write || !fp2->f_op->write){
                printk("Write operation not permitted \n");
                rc = -EPERM;
                goto out;
        }
	
	rc = is_same_file(fp1,fp2);
        if(rc){
                printk("Input and output files are same \n");
                rc = -EINVAL;
                goto out;
        }
	
	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if(IS_ERR(buf)){
		printk("Error while allocationg temporary buffer for reading and writing \n");
                rc = -PTR_ERR(key);
                goto out;
        }

	/* Add info about key in preamble during encryption */
	if(flag == 1)
	{	
		rc=add_preamble(fp_temp,key,keylen);
		if(rc< 0){
			printk("Error adding preamble to the outfile\n");
			goto out;
		}
	}

	/* Verify hashed key stored in preamble during decryption */
	if(flag == 0)
	{
		rc=verify_preamble(fp1,key,keylen);
		if(rc<0){
			printk("Error verifying preamble in the encrypted file\n");
			goto out;
		}
	}
	
	/* read and write actual data */
	while(1){
		fs=get_fs();
		set_fs(get_ds());
		
		rbytes = fp1->f_op->read(fp1,buf,PAGE_SIZE,&fp1->f_pos);
		
		if(rbytes < 0){
			printk("Failed reading input file\n");
			set_fs(fs);
			rc= -EIO;
			goto out;
		}

		if (rbytes == 0){
			printk("Reached end of file while reading \n");
			rc= 0;
			goto out_rename;
		}
		
		/* If flag is set as 1, input file is encrypted */
		if(flag == 1){
			rc=encrypt_decrypt_file(buf,key,rbytes,flag);
			if(rc < 0){
				printk("Encrypt failure\n");
				goto out;
			}
		}
		/* If flag is set as 0, input file is decrypted */
		else if(flag == 0){
			rc=encrypt_decrypt_file(buf,key,rbytes,flag);
			if(rc < 0){
				printk("Decrypt failure \n");
				goto out;
			}
		}

		wbytes = fp_temp->f_op->write(fp_temp,buf,rbytes,&fp_temp->f_pos);
		
		if(wbytes < 0){
			printk("Failed writing output file\n");
                        set_fs(fs);
                        rc= -EIO;
                        goto out;
		}
		set_fs(fs);
	}
	
out_rename:
	flag_delete_temp=1;
	rc = rename_temp_file(fp_temp,fp2);
	if(rc)
		printk("Rename operation failed \n");

out:	
	if(flag_delete_temp==0){
		if(rc<0){
			if(delete_partial_file(fp_temp))
				printk("Deleting partial temp file failed \n");
		}
	}
	printk("flag_outfile = %d \n",flag_outfile);
	if(flag_outfile==0){
		if(rc < 0){
			if(delete_partial_file(fp2))
				printk("Deleting out file failed\n");
        	}
	}
	if(fp_temp)
		filp_close(fp_temp,NULL);
	if(buf)
		kfree(buf);
	if(fp2)
		filp_close(fp2,NULL);
	if(fp1)
		filp_close(fp1,NULL);
	if(IS_ERR(f2name))
		putname(f2name);
	if(IS_ERR(f1name))
		putname(f1name);
	return rc;
}
Ejemplo n.º 18
0
void __init mount_block_root(char *name, int flags)
{
	char *fs_names = __getname_gfp(GFP_KERNEL
		| __GFP_NOTRACK_FALSE_POSITIVE);
	char *p;
#ifdef CONFIG_BLOCK
	char b[BDEVNAME_SIZE];
#else
	const char *b = name;
#endif

	get_fs_names(fs_names);
retry:
	for (p = fs_names; *p; p += strlen(p)+1) {
		int err = do_mount_root(name, p, flags, root_mount_data);
		switch (err) {
			case 0:
				goto out;
			case -EACCES:
				flags |= MS_RDONLY;
				goto retry;
			case -EINVAL:
				continue;
		}
	        /*
		 * Allow the user to distinguish between failed sys_open
		 * and bad superblock on root device.
		 * and give them a list of the available devices
		 */
#ifdef CONFIG_BLOCK
		__bdevname(ROOT_DEV, b);
#endif
		printk("VFS: Cannot open root device \"%s\" or %s\n",
				root_device_name, b);
		printk("Please append a correct \"root=\" boot option; here are the available partitions:\n");

		printk_all_partitions();
#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
		printk("DEBUG_BLOCK_EXT_DEVT is enabled, you need to specify "
		       "explicit textual name for \"root=\" boot option.\n");
#endif
		printk("VFS: Unable to mount root fs on %s\n", b);
		printk("User configuration error - no valid root filesystem found\n");
		panic("Invalid configuration from end user prevents continuing");
	}

	printk("List of all partitions:\n");
	printk_all_partitions();
	printk("No filesystem could mount root, tried: ");
	for (p = fs_names; *p; p += strlen(p)+1)
		printk(" %s", p);
	printk("\n");
#ifdef CONFIG_BLOCK
	__bdevname(ROOT_DEV, b);
#endif
	printk("VFS: Unable to mount root fs on %s\n", b);
	printk("User configuration error - no valid root filesystem found\n");
	panic("Invalid configuration from end user prevents continuing");
out:
	putname(fs_names);
}
Ejemplo n.º 19
0
/*
 * Executes a program.
 */
PUBLIC int sys_execve(const char *filename, const char **argv, const char **envp)
{
	int i;                /* Loop index.          */
	struct inode *inode;  /* File inode.          */
	struct region *reg;   /* Process region.      */
	addr_t entry;         /* Program entry point. */
	addr_t sp;            /* User stack pointer.  */
	char *name;           /* File name.           */
	char stack[ARG_MAX];  /* Stack size.          */

	/* Get file name. */
	if ((name = getname(filename)) == NULL)
		return (curr_proc->errno);

	/* Build arguments before freeing user memory. */
	kmemset(stack, 0, ARG_MAX);
	if (!(sp = buildargs(stack, ARG_MAX, argv, envp)))
	{
		putname(name);
		return (curr_proc->errno);
	}

	/* Get file's inode. */
	if ((inode = inode_name(name)) == NULL)
	{
		putname(name);
		return (curr_proc->errno);
	}

	/* Not a regular file. */
	if (!S_ISREG(inode->mode))
	{
		putname(name);
		inode_put(inode);
		return (-EACCES);
	}

	/* Not allowed. */
	if (!permission(inode->mode, inode->uid, inode->gid, curr_proc, MAY_EXEC, 0))
	{
		putname(name);
		inode_put(inode);
		return (-EACCES);
	}

	/* Close file descriptors. */
	for (i = 0; i < OPEN_MAX; i++)
	{
		if (curr_proc->close & (1 << i))
			do_close(i);
	}

	/* Detach process memory regions. */
	for (i = 0; i < NR_PREGIONS; i++)
		detachreg(curr_proc, &curr_proc->pregs[i]);
	
	/* Reset signal handlers. */
	curr_proc->restorer = NULL;
	for (i = 0; i < NR_SIGNALS; i++)
	{
		if (curr_proc->handlers[i] != SIG_DFL)
		{
			if (curr_proc->handlers[i] != SIG_IGN)
				curr_proc->handlers[i] = SIG_DFL;
		}
	}
	
	/* Load executable. */
	if (!(entry = load_elf32(inode)))
		goto die0;

	/* Attach stack region. */
	if ((reg = allocreg(S_IRUSR | S_IWUSR, PAGE_SIZE, REGION_DOWNWARDS)) == NULL)
		goto die0;
	if (attachreg(curr_proc, STACK(curr_proc), USTACK_ADDR - 1, reg))
		goto die1;
	unlockreg(reg);

	/* Attach heap region. */
	if ((reg = allocreg(S_IRUSR | S_IWUSR, PAGE_SIZE, REGION_UPWARDS)) == NULL)
		goto die0;
	if (attachreg(curr_proc, HEAP(curr_proc), UHEAP_ADDR, reg))
		goto die1;
	unlockreg(reg);
	
	inode_put(inode);
	putname(name);

	kmemcpy((void *)(USTACK_ADDR - ARG_MAX), stack, ARG_MAX);
	
	user_mode(entry, sp);
	
	/* Will not return. */
	return (0);

die1:
	unlockreg(reg);
	freereg(reg);
die0:
	inode_put(inode);
	putname(name);
	die(((SIGSEGV & 0xff) << 16) | (1 << 9));
	return (-1);
}
Ejemplo n.º 20
0
asmlinkage int sys_acct(const char *name)
{
    struct inode *inode = (struct inode *)0;
    char *tmp;
    int error;

    if (!suser())
        return -EPERM;

    if (name == (char *)0) {
        if (acct_active) {
            if (acct_file.f_op->release)
                acct_file.f_op->release(acct_file.f_inode, &acct_file);

            if (acct_file.f_inode != (struct inode *) 0)
                iput(acct_file.f_inode);

            acct_active = 0;
        }
        return 0;
    } else {
        if (!acct_active) {

            if ((error = getname(name, &tmp)) != 0)
                return (error);

            error = open_namei(tmp, O_RDWR, 0600, &inode, 0);
            putname(tmp);

            if (error)
                return (error);

            if (!S_ISREG(inode->i_mode)) {
                iput(inode);
                return -EACCES;
            }

            if (!inode->i_op || !inode->i_op->default_file_ops ||
                    !inode->i_op->default_file_ops->write) {
                iput(inode);
                return -EIO;
            }

            acct_file.f_mode = 3;
            acct_file.f_flags = 0;
            acct_file.f_count = 1;
            acct_file.f_inode = inode;
            acct_file.f_pos = inode->i_size;
            acct_file.f_reada = 0;
            acct_file.f_op = inode->i_op->default_file_ops;

            if (acct_file.f_op->open)
                if (acct_file.f_op->open(acct_file.f_inode, &acct_file)) {
                    iput(inode);
                    return -EIO;
                }

            acct_active = 1;
            return 0;
        } else
            return -EBUSY;
    }
}
Ejemplo n.º 21
0
int unionfs_ioctl_addbranch(struct inode *inode, unsigned int cmd,
			    unsigned long arg)
{
	int err;
	struct unionfs_addbranch_args *addargs = NULL;
	struct nameidata nd;
	char *path = NULL;
	int gen;
	int i;
	int count;

	int pobjects;

	struct vfsmount **new_hidden_mnt = NULL;
	struct inode **new_uii_inode = NULL;
	struct dentry **new_udi_dentry = NULL;
	struct super_block **new_usi_sb = NULL;
	int *new_branchperms = NULL;
	atomic_t *new_counts = NULL;

	print_entry_location();

	err = -ENOMEM;
	addargs = KMALLOC(sizeof(struct unionfs_addbranch_args), GFP_UNIONFS);
	if (!addargs)
		goto out;

	err = -EFAULT;
	if (copy_from_user
	    (addargs, (void *)arg, sizeof(struct unionfs_addbranch_args)))
		goto out;

	err = -EINVAL;
	if (addargs->ab_perms & ~(MAY_READ | MAY_WRITE))
		goto out;
	if (!(addargs->ab_perms & MAY_READ))
		goto out;

	err = -E2BIG;
	if (sbend(inode->i_sb) > FD_SETSIZE)
		goto out;

	err = -ENOMEM;
	if (!(path = getname(addargs->ab_path)))
		goto out;

	err = path_lookup(path, LOOKUP_FOLLOW, &nd);

	RECORD_PATH_LOOKUP(&nd);
	if (err)
		goto out;
	if ((err = check_branch(&nd))) {
		path_release(&nd);
		RECORD_PATH_RELEASE(&nd);
		goto out;
	}

	unionfs_write_lock(inode->i_sb);
	lock_dentry(inode->i_sb->s_root);

	err = -EINVAL;
	if (addargs->ab_branch < 0
	    || (addargs->ab_branch > (sbend(inode->i_sb) + 1)))
		goto out;

	if ((err = newputmap(inode->i_sb)))
		goto out;

	stopd(inode->i_sb)->b_end++;
	dtopd(inode->i_sb->s_root)->udi_bcount++;
	set_dbend(inode->i_sb->s_root, dbend(inode->i_sb->s_root) + 1);
	itopd(inode->i_sb->s_root->d_inode)->b_end++;

	atomic_inc(&stopd(inode->i_sb)->usi_generation);
	gen = atomic_read(&stopd(inode->i_sb)->usi_generation);

	pobjects = (sbend(inode->i_sb) + 1) - UNIONFS_INLINE_OBJECTS;
	if (pobjects > 0) {
		/* Reallocate the dynamic structures. */
		new_hidden_mnt =
		    KMALLOC(sizeof(struct vfsmount *) * pobjects, GFP_UNIONFS);
		new_udi_dentry =
		    KMALLOC(sizeof(struct dentry *) * pobjects, GFP_UNIONFS);
		new_uii_inode =
		    KMALLOC(sizeof(struct inode *) * pobjects, GFP_UNIONFS);
		new_usi_sb =
		    KMALLOC(sizeof(struct super_block *) * pobjects,
			    GFP_UNIONFS);
		new_counts = KMALLOC(sizeof(atomic_t) * pobjects, GFP_UNIONFS);
		new_branchperms = KMALLOC(sizeof(int) * pobjects, GFP_UNIONFS);
		if (!new_hidden_mnt || !new_udi_dentry || !new_uii_inode
		    || !new_counts || !new_usi_sb || !new_branchperms) {
			err = -ENOMEM;
			goto out;
		}
		memset(new_hidden_mnt, 0, sizeof(struct vfsmount *) * pobjects);
		memset(new_udi_dentry, 0, sizeof(struct dentry *) * pobjects);
		memset(new_uii_inode, 0, sizeof(struct inode *) * pobjects);
		memset(new_usi_sb, 0, sizeof(struct super_block *) * pobjects);
		memset(new_branchperms, 0, sizeof(int) * pobjects);
	}

	/* Copy the in-place values to our new structure. */
	for (i = UNIONFS_INLINE_OBJECTS; i < addargs->ab_branch; i++) {
		int j = i - UNIONFS_INLINE_OBJECTS;

		count = branch_count(inode->i_sb, i);
		atomic_set(&(new_counts[j]), count);

		new_branchperms[j] = branchperms(inode->i_sb, i);
		new_hidden_mnt[j] = stohiddenmnt_index(inode->i_sb, i);

		new_usi_sb[j] = stohs_index(inode->i_sb, i);
		new_udi_dentry[j] = dtohd_index(inode->i_sb->s_root, i);
		new_uii_inode[j] = itohi_index(inode->i_sb->s_root->d_inode, i);
	}

	/* Shift the ends to the right (only handle reallocated bits). */
	for (i = sbend(inode->i_sb) - 1; i >= (int)addargs->ab_branch; i--) {
		int j = i + 1;
		int perms;
		struct vfsmount *hm;
		struct super_block *hs;
		struct dentry *hd;
		struct inode *hi;
		int pmindex;

		count = branch_count(inode->i_sb, i);
		perms = branchperms(inode->i_sb, i);
		hm = stohiddenmnt_index(inode->i_sb, i);
		hs = stohs_index(inode->i_sb, i);
		hd = dtohd_index(inode->i_sb->s_root, i);
		hi = itohi_index(inode->i_sb->s_root->d_inode, i);

		/* Update the newest putmap, so it is correct for later. */
		pmindex = stopd(inode->i_sb)->usi_lastputmap;
		pmindex -= stopd(inode->i_sb)->usi_firstputmap;
		stopd(inode->i_sb)->usi_putmaps[pmindex]->map[i] = j;

		if (j >= UNIONFS_INLINE_OBJECTS) {
			j -= UNIONFS_INLINE_OBJECTS;
			atomic_set(&(new_counts[j]), count);
			new_branchperms[j] = perms;
			new_hidden_mnt[j] = hm;
			new_usi_sb[j] = hs;
			new_udi_dentry[j] = hd;
			new_uii_inode[j] = hi;
		} else {
			set_branch_count(inode->i_sb, j, count);
			set_branchperms(inode->i_sb, j, perms);
			set_stohiddenmnt_index(inode->i_sb, j, hm);
			set_stohs_index(inode->i_sb, j, hs);
			set_dtohd_index(inode->i_sb->s_root, j, hd);
			set_itohi_index(inode->i_sb->s_root->d_inode, j, hi);
		}
	}

	/* Now we can free the old ones. */
	KFREE(dtopd(inode->i_sb->s_root)->udi_dentry_p);
	KFREE(itopd(inode->i_sb->s_root->d_inode)->uii_inode_p);
	KFREE(stopd(inode->i_sb)->usi_hidden_mnt_p);
	KFREE(stopd(inode->i_sb)->usi_sb_p);
	KFREE(stopd(inode->i_sb)->usi_sbcount_p);
	KFREE(stopd(inode->i_sb)->usi_branchperms_p);

	/* Update the real pointers. */
	dtohd_ptr(inode->i_sb->s_root) = new_udi_dentry;
	itohi_ptr(inode->i_sb->s_root->d_inode) = new_uii_inode;
	stohiddenmnt_ptr(inode->i_sb) = new_hidden_mnt;
	stohs_ptr(inode->i_sb) = new_usi_sb;
	stopd(inode->i_sb)->usi_sbcount_p = new_counts;
	stopd(inode->i_sb)->usi_branchperms_p = new_branchperms;

	/* Re-NULL the new ones so we don't try to free them. */
	new_hidden_mnt = NULL;
	new_udi_dentry = NULL;
	new_usi_sb = NULL;
	new_uii_inode = NULL;
	new_counts = NULL;
	new_branchperms = NULL;

	/* Put the new dentry information into it's slot. */
	set_dtohd_index(inode->i_sb->s_root, addargs->ab_branch, nd.dentry);
	set_itohi_index(inode->i_sb->s_root->d_inode, addargs->ab_branch,
			igrab(nd.dentry->d_inode));
	set_branchperms(inode->i_sb, addargs->ab_branch, addargs->ab_perms);
	set_branch_count(inode->i_sb, addargs->ab_branch, 0);
	set_stohiddenmnt_index(inode->i_sb, addargs->ab_branch, nd.mnt);
	set_stohs_index(inode->i_sb, addargs->ab_branch, nd.dentry->d_sb);

	atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen);
	atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen);

	fixputmaps(inode->i_sb);

      out:
	unlock_dentry(inode->i_sb->s_root);
	unionfs_write_unlock(inode->i_sb);

	KFREE(new_hidden_mnt);
	KFREE(new_udi_dentry);
	KFREE(new_uii_inode);
	KFREE(new_usi_sb);
	KFREE(new_counts);
	KFREE(new_branchperms);
	KFREE(addargs);
	if (path)
		putname(path);

	print_exit_status(err);

	return err;
}
Ejemplo n.º 22
0
/* Copy parameters and call proper function */
static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, caddr_t addr)
{
    int ret;

    switch (cmd) {
    case Q_QUOTAON: {
        char *pathname;

        if (IS_ERR(pathname = getname(addr)))
            return PTR_ERR(pathname);
        ret = sb->s_qcop->quota_on(sb, type, id, pathname);
        putname(pathname);
        return ret;
    }
    case Q_QUOTAOFF:
        return sb->s_qcop->quota_off(sb, type);

    case Q_GETFMT: {
        __u32 fmt;

        fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
        if (copy_to_user(addr, &fmt, sizeof(fmt)))
            return -EFAULT;
        return 0;
    }
    case Q_GETINFO: {
        struct if_dqinfo info;

        if ((ret = sb->s_qcop->get_info(sb, type, &info)))
            return ret;
        if (copy_to_user(addr, &info, sizeof(info)))
            return -EFAULT;
        return 0;
    }
    case Q_SETINFO: {
        struct if_dqinfo info;

        if (copy_from_user(&info, addr, sizeof(info)))
            return -EFAULT;
        return sb->s_qcop->set_info(sb, type, &info);
    }
    case Q_GETQUOTA: {
        struct if_dqblk idq;

        if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq)))
            return ret;
        if (copy_to_user(addr, &idq, sizeof(idq)))
            return -EFAULT;
        return 0;
    }
    case Q_SETQUOTA: {
        struct if_dqblk idq;

        if (copy_from_user(&idq, addr, sizeof(idq)))
            return -EFAULT;
        return sb->s_qcop->set_dqblk(sb, type, id, &idq);
    }
    case Q_SYNC:
        return sb->s_qcop->quota_sync(sb, type);

    case Q_XQUOTAON:
    case Q_XQUOTAOFF:
    case Q_XQUOTARM: {
        __u32 flags;

        if (copy_from_user(&flags, addr, sizeof(flags)))
            return -EFAULT;
        return sb->s_qcop->set_xstate(sb, flags, cmd);
    }
    case Q_XGETQSTAT: {
        struct fs_quota_stat fqs;

        if ((ret = sb->s_qcop->get_xstate(sb, &fqs)))
            return ret;
        if (copy_to_user(addr, &fqs, sizeof(fqs)))
            return -EFAULT;
        return 0;
    }
    case Q_XSETQLIM: {
        struct fs_disk_quota fdq;

        if (copy_from_user(&fdq, addr, sizeof(fdq)))
            return -EFAULT;
        return sb->s_qcop->set_xquota(sb, type, id, &fdq);
    }
    case Q_XGETQUOTA: {
        struct fs_disk_quota fdq;

        if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq)))
            return ret;
        if (copy_to_user(addr, &fdq, sizeof(fdq)))
            return -EFAULT;
        return 0;
    }
    /* We never reach here unless validity check is broken */
    default:
        BUG();
    }
    return 0;
}
Ejemplo n.º 23
0
static inline int solaris_S(struct file *filp, unsigned int fd, unsigned int cmd, u32 arg)
{
	char *p;
	int ret;
	mm_segment_t old_fs;
	struct strioctl si;
	struct inode *ino;
        struct sol_socket_struct *sock;
        struct module_info *mi;

        ino = filp->f_dentry->d_inode;
        if (! ino->i_sock)
		return -EBADF;
        sock = filp->private_data;
        if (! sock) {
                printk("solaris_S: NULL private_data\n");
                return -EBADF;
        }
        if (sock->magic != SOLARIS_SOCKET_MAGIC) {
                printk("solaris_S: invalid magic\n");
                return -EBADF;
        }
        

	switch (cmd & 0xff) {
	case 1: /* I_NREAD */
		return -ENOSYS;
	case 2: /* I_PUSH */
        {
		p = getname ((char *)A(arg));
		if (IS_ERR (p))
			return PTR_ERR(p);
                ret = -EINVAL;
                for (mi = module_table; mi->name; mi++) {
                        if (strcmp(mi->name, p) == 0) {
                                sol_module m;
                                if (sock->modcount >= MAX_NR_STREAM_MODULES) {
                                        ret = -ENXIO;
                                        break;
                                }
                                m = (sol_module) (mi - module_table);
                                sock->module[sock->modcount++] = m;
                                ret = 0;
                                break;
                        }
                }
		putname (p);
		return ret;
        }
	case 3: /* I_POP */
                if (sock->modcount <= 0) return -EINVAL;
                sock->modcount--;
		return 0;
        case 4: /* I_LOOK */
        {
        	const char *p;
                if (sock->modcount <= 0) return -EINVAL;
                p = module_table[(unsigned)sock->module[sock->modcount]].name;
                if (copy_to_user ((char *)A(arg), p, strlen(p)))
                	return -EFAULT;
                return 0;
        }
	case 5: /* I_FLUSH */
		return 0;
	case 8: /* I_STR */
		if (copy_from_user(&si, (struct strioctl *)A(arg), sizeof(struct strioctl)))
			return -EFAULT;
                /* We ignore what module is actually at the top of stack. */
		switch ((si.cmd >> 8) & 0xff) {
		case 'I':
                        return solaris_sockmod(fd, si.cmd, si.data);
		case 'T':
                        return solaris_timod(fd, si.cmd, si.data, si.len,
                                                &((struct strioctl*)A(arg))->len);
		default:
			return solaris_ioctl(fd, si.cmd, si.data);
		}
	case 9: /* I_SETSIG */
		return sys_ioctl(fd, FIOSETOWN, current->pid);
	case 10: /* I_GETSIG */
		old_fs = get_fs();
		set_fs(KERNEL_DS);
		sys_ioctl(fd, FIOGETOWN, (unsigned long)&ret);
		set_fs(old_fs);
		if (ret == current->pid) return 0x3ff;
		else return -EINVAL;
	case 11: /* I_FIND */
        {
                int i;
		p = getname ((char *)A(arg));
		if (IS_ERR (p))
			return PTR_ERR(p);
                ret = 0;
                for (i = 0; i < sock->modcount; i++) {
                        unsigned m = sock->module[i];
                        if (strcmp(module_table[m].name, p) == 0) {
                                ret = 1;
                                break;
                        } 
                }
		putname (p);
		return ret;
        }
	case 19: /* I_SWROPT */
	case 32: /* I_SETCLTIME */
		return 0;	/* Lie */
	}
	return -ENOSYS;
}
Ejemplo n.º 24
0
/* Handle requests to old interface */
static int do_compat_quotactl(struct super_block *sb, int type, int cmd, qid_t id, caddr_t addr)
{
    int ret;

    switch (cmd) {
    case Q_COMP_QUOTAON: {
        char *pathname;

        if (IS_ERR(pathname = getname(addr)))
            return PTR_ERR(pathname);
#ifdef CONFIG_QIFACE_V1
        ret = sb->s_qcop->quota_on(sb, type, QFMT_VFS_OLD, pathname);
#else
        ret = sb->s_qcop->quota_on(sb, type, QFMT_VFS_V0, pathname);
#endif
        putname(pathname);
        return ret;
    }
    case Q_COMP_QUOTAOFF:
        return sb->s_qcop->quota_off(sb, type);
    case Q_COMP_SYNC:
        return sb->s_qcop->quota_sync(sb, type);
#ifdef CONFIG_QIFACE_V1
    case Q_V1_RSQUASH: {
        int flag;

        if (copy_from_user(&flag, addr, sizeof(flag)))
            return -EFAULT;
        return v1_set_rsquash(sb, type, flag);
    }
    case Q_V1_GETQUOTA: {
        struct v1c_mem_dqblk mdq;

        if ((ret = v1_get_dqblk(sb, type, id, &mdq)))
            return ret;
        if (copy_to_user(addr, &mdq, sizeof(mdq)))
            return -EFAULT;
        return 0;
    }
    case Q_V1_SETQLIM:
    case Q_V1_SETUSE:
    case Q_V1_SETQUOTA: {
        struct v1c_mem_dqblk mdq;

        if (copy_from_user(&mdq, addr, sizeof(mdq)))
            return -EFAULT;
        return v1_set_dqblk(sb, type, cmd, id, &mdq);
    }
    case Q_V1_GETSTATS: {
        struct v1c_dqstats dst;

        v1_get_stats(&dst);
        if (copy_to_user(addr, &dst, sizeof(dst)))
            return -EFAULT;
        return 0;
    }
#endif
#ifdef CONFIG_QIFACE_V2
    case Q_V2_GETINFO: {
        struct v2c_mem_dqinfo info;

        if ((ret = v2_get_info(sb, type, &info)))
            return ret;
        if (copy_to_user(addr, &info, sizeof(info)))
            return -EFAULT;
        return 0;
    }
    case Q_V2_SETFLAGS:
    case Q_V2_SETGRACE:
    case Q_V2_SETINFO: {
        struct v2c_mem_dqinfo info;

        if (copy_from_user(&info, addr, sizeof(info)))
            return -EFAULT;

        return v2_set_info(sb, type, cmd, &info);
    }
    case Q_V2_GETQUOTA: {
        struct v2c_mem_dqblk mdq;

        if ((ret = v2_get_dqblk(sb, type, id, &mdq)))
            return ret;
        if (copy_to_user(addr, &mdq, sizeof(mdq)))
            return -EFAULT;
        return 0;
    }
    case Q_V2_SETUSE:
    case Q_V2_SETQLIM:
    case Q_V2_SETQUOTA: {
        struct v2c_mem_dqblk mdq;

        if (copy_from_user(&mdq, addr, sizeof(mdq)))
            return -EFAULT;
        return v2_set_dqblk(sb, type, cmd, id, &mdq);
    }
    case Q_V2_GETSTATS: {
        struct v2c_dqstats dst;

        v2_get_stats(&dst);
        if (copy_to_user(addr, &dst, sizeof(dst)))
            return -EFAULT;
        return 0;
    }
#endif
    }
    BUG();
    return 0;
}