static int appcl_lsm_inode_init_security(struct inode *inode, struct inode *dir,
                                        const struct qstr *qstr, const char **name,
					void **value, size_t *len)
{
	struct inode_security_label *ilabel = inode->i_security;
	struct inode_security_label *dirlabel = dir->i_security;
	const char *t_xvalue = NULL;
	const char *xvalue = NULL;

	if (name)
		*name = XATTR_APPCL_SUFFIX;

	if (value && len) {
		rcu_read_lock();
		t_xvalue = kstrndup(dirlabel->xvalue, APPCL_LNG_LABEL, GFP_NOFS);
		rcu_read_unlock();
		if (t_xvalue) {
			ilabel = dirlabel;
			ilabel->flags = APPCL_ATTR_INIT;
		}

		xvalue = kstrndup(t_xvalue, APPCL_LNG_LABEL, GFP_NOFS);
		*value = kstrndup(xvalue, APPCL_LNG_LABEL, GFP_NOFS);
		if (*value == NULL)
			return -ENOMEM;

		*len = strlen(t_xvalue);
	}

	return 0;
}
Example #2
0
static int migrate_nfs_validate_text_mount_data169(/*void *options,*/
    struct nfs_parsed_mount_data *args/*,
					const char *dev_name*/)
{
    int port = 0;
    //int max_namelen = PAGE_SIZE;
    //int max_pathlen = NFS_MAXPATHLEN;
    struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
    char mnt_addr[] = "162.105.146.169";
    char mnt_hostname[] = "162.105.146.169";
    char mnt_dirpath[] = "/home/disk1";

    //if (nfs_parse_mount_options((char *)options, args) == 0)
    //	return -EINVAL;
    /* security_sb_parse_opts_str() */
    /* address */
    args->nfs_server.addrlen =
        rpc_pton(args->net, mnt_addr, strlen(mnt_addr),
                 (struct sockaddr *)
                 &args->nfs_server.address,
                 sizeof(args->nfs_server.address));
    if (args->nfs_server.addrlen == 0)
        dfprintk(MOUNT, "zql: invalid address\n");
    /* version vers=3 */
    args->flags |= NFS_MOUNT_VER3;
    args->version = 3;
    /* proto=tcp, Opt_xprt_tcp */
    args->flags |= NFS_MOUNT_TCP;
    args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
    /* mountvers=3 */
    args->mount_server.version = 3;
    /* mountproto=udp */
    args->mount_server.protocol = XPRT_TRANSPORT_UDP;
    /* mountport=20048 */
    args->mount_server.port = 20048;

    if (!nfs_verify_server_address(sap))
        goto out_no_address;

    if (args->version == 4) {
        dfprintk(MOUNT, "zql: version 4 error not supported\n");
    } else
        nfs_set_mount_transport_protocol(args);

    nfs_set_port(sap, &args->nfs_server.port, port);

    //return nfs_parse_devname(dev_name,
    //			   &args->nfs_server.hostname,
    //			   max_namelen,
    //			   &args->nfs_server.export_path,
    //			   max_pathlen);
    args->nfs_server.hostname = kstrndup(mnt_hostname, strlen(mnt_hostname), GFP_KERNEL);
    args->nfs_server.export_path = kstrndup(mnt_dirpath, strlen(mnt_dirpath), GFP_KERNEL);
    return 0;

out_no_address:
    dfprintk(MOUNT, "zql: NFS: mount program didn't pass remote address\n");
    return -EINVAL;
}
static ssize_t driver_override_store(struct device *_dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{
	struct amba_device *dev = to_amba_device(_dev);
	char *driver_override, *old = dev->driver_override, *cp;

	if (count > PATH_MAX)
		return -EINVAL;

	driver_override = kstrndup(buf, count, GFP_KERNEL);
	if (!driver_override)
		return -ENOMEM;

	cp = strchr(driver_override, '\n');
	if (cp)
		*cp = '\0';

	if (strlen(driver_override)) {
		dev->driver_override = driver_override;
	} else {
	       kfree(driver_override);
	       dev->driver_override = NULL;
	}

	kfree(old);

	return count;
}
Example #4
0
static ssize_t driver_override_store(struct device *_dev,
				     struct device_attribute *attr,
				     const char *buf, size_t count)
{
	struct amba_device *dev = to_amba_device(_dev);
	char *driver_override, *old, *cp;

	/* We need to keep extra room for a newline */
	if (count >= (PAGE_SIZE - 1))
		return -EINVAL;

	driver_override = kstrndup(buf, count, GFP_KERNEL);
	if (!driver_override)
		return -ENOMEM;

	cp = strchr(driver_override, '\n');
	if (cp)
		*cp = '\0';

	device_lock(_dev);
	old = dev->driver_override;
	if (strlen(driver_override)) {
		dev->driver_override = driver_override;
	} else {
	       kfree(driver_override);
	       dev->driver_override = NULL;
	}
	device_unlock(_dev);

	kfree(old);

	return count;
}
Example #5
0
static struct knav_queue *__knav_queue_open(struct knav_queue_inst *inst,
				      const char *name, unsigned flags)
{
	struct knav_queue *qh;
	unsigned id;
	int ret = 0;

	qh = devm_kzalloc(inst->kdev->dev, sizeof(*qh), GFP_KERNEL);
	if (!qh)
		return ERR_PTR(-ENOMEM);

	qh->flags = flags;
	qh->inst = inst;
	id = inst->id - inst->qmgr->start_queue;
	qh->reg_push = &inst->qmgr->reg_push[id];
	qh->reg_pop = &inst->qmgr->reg_pop[id];
	qh->reg_peek = &inst->qmgr->reg_peek[id];

	/* first opener? */
	if (!knav_queue_is_busy(inst)) {
		struct knav_range_info *range = inst->range;

		inst->name = kstrndup(name, KNAV_NAME_SIZE, GFP_KERNEL);
		if (range->ops && range->ops->open_queue)
			ret = range->ops->open_queue(range, inst, flags);

		if (ret) {
			devm_kfree(inst->kdev->dev, qh);
			return ERR_PTR(ret);
		}
	}
	list_add_tail_rcu(&qh->list, &inst->handles);
	return qh;
}
struct ias_object *irias_new_object( char *name, int id)
{
    struct ias_object *obj;

    IRDA_DEBUG( 4, "%s()\n", __func__);

    obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC);
    if (obj == NULL) {
        IRDA_WARNING("%s(), Unable to allocate object!\n",
                     __func__);
        return NULL;
    }

    obj->magic = IAS_OBJECT_MAGIC;
    obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
    if (!obj->name) {
        IRDA_WARNING("%s(), Unable to allocate name!\n",
                     __func__);
        kfree(obj);
        return NULL;
    }
    obj->id = id;

    obj->attribs = hashbin_new(HB_LOCK);

    if (obj->attribs == NULL) {
        IRDA_WARNING("%s(), Unable to allocate attribs!\n",
                     __func__);
        kfree(obj->name);
        kfree(obj);
        return NULL;
    }

    return obj;
}
Example #7
0
static ssize_t resume_store(struct kobject *kobj, struct kobj_attribute *attr,
			    const char *buf, size_t n)
{
	dev_t res;
	int len = n;
	char *name;

	if (len && buf[len-1] == '\n')
		len--;
	name = kstrndup(buf, len, GFP_KERNEL);
	if (!name)
		return -ENOMEM;

	res = name_to_dev_t(name);
	kfree(name);
	if (!res)
		return -EINVAL;

	lock_system_sleep();
	swsusp_resume_device = res;
	unlock_system_sleep();
	pr_info("Starting manual resume from disk\n");
	noresume = 0;
	software_resume();
	return n;
}
Example #8
0
static int alloc_defdata(struct tcf_defact *d, char *defdata)
{
	d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL);
	if (unlikely(!d->tcfd_defdata))
		return -ENOMEM;

	return 0;
}
Example #9
0
static char *
repl_kstrndup(const char *s, size_t max, gfp_t gfp)
{
    char *ret_val;
    ret_val = kstrndup(s, max, gfp);
    
    if (ret_val != NULL)
        klc_add_alloc((void *)ret_val, strnlen(s, max) + 1, stack_depth);
    
    return ret_val;
}
Example #10
0
static int
CIFSParseMFSymlink(const u8 *buf,
		   unsigned int buf_len,
		   unsigned int *_link_len,
		   char **_link_str)
{
	int rc;
	unsigned int link_len;
	const char *md5_str1;
	const char *link_str;
	u8 md5_hash[16];
	char md5_str2[34];

	if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
		return -EINVAL;

	md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
	link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];

	rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
	if (rc != 1)
		return -EINVAL;

	rc = symlink_hash(link_len, link_str, md5_hash);
	if (rc) {
		cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
		return rc;
	}

	snprintf(md5_str2, sizeof(md5_str2),
		 CIFS_MF_SYMLINK_MD5_FORMAT,
		 CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));

	if (strncmp(md5_str1, md5_str2, 17) != 0)
		return -EINVAL;

	if (_link_str) {
		*_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
		if (!*_link_str)
			return -ENOMEM;
	}

	*_link_len = link_len;
	return 0;
}
Example #11
0
static int gb_lights_light_config(struct gb_lights *glights, u8 id)
{
	struct gb_light *light = &glights->lights[id];
	struct gb_lights_get_light_config_request req;
	struct gb_lights_get_light_config_response conf;
	int ret;
	int i;

	light->glights = glights;
	light->id = id;

	req.id = id;

	ret = gb_operation_sync(glights->connection,
				GB_LIGHTS_TYPE_GET_LIGHT_CONFIG,
				&req, sizeof(req), &conf, sizeof(conf));
	if (ret < 0)
		return ret;

	if (!conf.channel_count)
		return -EINVAL;
	if (!strlen(conf.name))
		return -EINVAL;

	light->channels_count = conf.channel_count;
	light->name = kstrndup(conf.name, NAMES_MAX, GFP_KERNEL);

	light->channels = kzalloc(light->channels_count *
				  sizeof(struct gb_channel), GFP_KERNEL);
	if (!light->channels)
		return -ENOMEM;

	/* First we collect all the configurations for all channels */
	for (i = 0; i < light->channels_count; i++) {
		light->channels[i].id = i;
		ret = gb_lights_channel_config(light, &light->channels[i]);
		if (ret < 0)
			return ret;
	}

	return 0;
}
Example #12
0
static ssize_t
get_string(struct l4fdx_client *client,
           char **s, unsigned *s_len,
           const char *buf, size_t size)
{
    size_t l = 0;

    if (client->enabled)
        return -EINVAL;

    if (*s)
        kfree(*s);

    while (l < size && buf[l] && buf[l] != '\n')
        ++l;
    *s     = kstrndup(buf, l, GFP_KERNEL);
    if (s_len)
        *s_len = l;
    return size;
}
Example #13
0
/*
 * Function ias_new_object (name, id)
 *
 *    Create a new IAS object
 *
 */
struct ias_object *irias_new_object( char *name, int id)
{
    struct ias_object *obj;

    IRDA_DEBUG( 4, "%s()\n", __func__);

    obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC);
    if (obj == NULL) {
        IRDA_WARNING("%s(), Unable to allocate object!\n",
                     __func__);
        return NULL;
    }

    obj->magic = IAS_OBJECT_MAGIC;
    obj->name = kstrndup(name, IAS_MAX_CLASSNAME, GFP_ATOMIC);
    if (!obj->name) {
        IRDA_WARNING("%s(), Unable to allocate name!\n",
                     __func__);
        kfree(obj);
        return NULL;
    }
    obj->id = id;

    /* Locking notes : the attrib spinlock has lower precendence
     * than the objects spinlock. Never grap the objects spinlock
     * while holding any attrib spinlock (risk of deadlock). Jean II */
    obj->attribs = hashbin_new(HB_LOCK);

    if (obj->attribs == NULL) {
        IRDA_WARNING("%s(), Unable to allocate attribs!\n",
                     __func__);
        kfree(obj->name);
        kfree(obj);
        return NULL;
    }

    return obj;
}
/**
 * pseries_of_derive_parent - basically like dirname(1)
 * @path:  the full_name of a node to be added to the tree
 *
 * Returns the node which should be the parent of the node
 * described by path.  E.g., for path = "/foo/bar", returns
 * the node with full_name = "/foo".
 */
struct device_node *pseries_of_derive_parent(const char *path)
{
	struct device_node *parent;
	char *parent_path = "/";
	const char *tail;

	/* We do not want the trailing '/' character */
	tail = kbasename(path) - 1;

	/* reject if path is "/" */
	if (!strcmp(path, "/"))
		return ERR_PTR(-EINVAL);

	if (tail > path) {
		parent_path = kstrndup(path, tail - path, GFP_KERNEL);
		if (!parent_path)
			return ERR_PTR(-ENOMEM);
	}
	parent = of_find_node_by_path(parent_path);
	if (strcmp(parent_path, "/"))
		kfree(parent_path);
	return parent ? parent : ERR_PTR(-EINVAL);
}
static char *extract_sharename(const char *treename)
{
	const char *src;
	char *delim, *dst;
	int len;

	
	src = treename + 2;

	
	delim = strchr(src, '\\');
	if (!delim)
		return ERR_PTR(-EINVAL);
	delim++;
	len = strlen(delim);

	
	dst = kstrndup(delim, len, GFP_KERNEL);
	if (!dst)
		return ERR_PTR(-ENOMEM);

	return dst;
}
Example #16
0
static char *extract_sharename(const char *treename)
{
	const char *src;
	char *delim, *dst;
	int len;

	/* skip double chars at the beginning */
	src = treename + 2;

	/* share name is always preceded by '\\' now */
	delim = strchr(src, '\\');
	if (!delim)
		return ERR_PTR(-EINVAL);
	delim++;
	len = strlen(delim);

	/* caller has to free the memory */
	dst = kstrndup(delim, len, GFP_KERNEL);
	if (!dst)
		return ERR_PTR(-ENOMEM);

	return dst;
}
Example #17
0
static int gb_lights_channel_config(struct gb_light *light,
				    struct gb_channel *channel)
{
	struct gb_lights_get_channel_config_response conf;
	struct gb_lights_get_channel_config_request req;
	struct gb_connection *connection = get_conn_from_light(light);
	struct led_classdev *cdev = get_channel_cdev(channel);
	char *name;
	int ret;

	req.light_id = light->id;
	req.channel_id = channel->id;

	ret = gb_operation_sync(connection, GB_LIGHTS_TYPE_GET_CHANNEL_CONFIG,
				&req, sizeof(req), &conf, sizeof(conf));
	if (ret < 0)
		return ret;

	channel->light = light;
	channel->mode = le32_to_cpu(conf.mode);
	channel->flags = le32_to_cpu(conf.flags);
	channel->color = le32_to_cpu(conf.color);
	channel->color_name = kstrndup(conf.color_name, NAMES_MAX, GFP_KERNEL);
	if (!channel->color_name)
		return -ENOMEM;
	channel->mode_name = kstrndup(conf.mode_name, NAMES_MAX, GFP_KERNEL);
	if (!channel->mode_name)
		return -ENOMEM;

	channel->led = cdev;

	name = kasprintf(GFP_KERNEL, "%s:%s:%s", light->name,
			 channel->color_name, channel->mode_name);
	if (!name)
		return -ENOMEM;

	cdev->name = name;

	cdev->max_brightness = conf.max_brightness;

	ret = channel_attr_groups_set(channel, cdev);
	if (ret < 0)
		return ret;

	gb_lights_led_operations_set(channel, cdev);

	/*
	 * If it is not a flash related channel (flash, torch or indicator) we
	 * are done here. If not, continue and fetch flash related
	 * configurations.
	 */
	if (!is_channel_flash(channel))
		return ret;

	light->has_flash = true;

	ret = gb_lights_channel_flash_config(channel);
	if (ret < 0)
		return ret;

	return ret;
}
Example #18
0
/*
 * This function fills in xfs_mount_t fields based on mount args.
 * Note: the superblock has _not_ yet been read in.
 *
 * Note that this function leaks the various device name allocations on
 * failure.  The caller takes care of them.
 */
STATIC int
xfs_parseargs(
	struct xfs_mount	*mp,
	char			*options,
	char			**mtpt)
{
	struct super_block	*sb = mp->m_super;
	char			*this_char, *value, *eov;
	int			dsunit = 0;
	int			dswidth = 0;
	int			iosize = 0;
	int			dmapi_implies_ikeep = 1;
	__uint8_t		iosizelog = 0;

	/*
	 * Copy binary VFS mount flags we are interested in.
	 */
	if (sb->s_flags & MS_RDONLY)
		mp->m_flags |= XFS_MOUNT_RDONLY;
	if (sb->s_flags & MS_DIRSYNC)
		mp->m_flags |= XFS_MOUNT_DIRSYNC;
	if (sb->s_flags & MS_SYNCHRONOUS)
		mp->m_flags |= XFS_MOUNT_WSYNC;

	/*
	 * Set some default flags that could be cleared by the mount option
	 * parsing.
	 */
	mp->m_flags |= XFS_MOUNT_BARRIER;
	mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
	mp->m_flags |= XFS_MOUNT_SMALL_INUMS;

	/*
	 * These can be overridden by the mount option parsing.
	 */
	mp->m_logbufs = -1;
	mp->m_logbsize = -1;

	if (!options)
		goto done;

	while ((this_char = strsep(&options, ",")) != NULL) {
		if (!*this_char)
			continue;
		if ((value = strchr(this_char, '=')) != NULL)
			*value++ = 0;

		if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			mp->m_logbufs = simple_strtoul(value, &eov, 10);
		} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			mp->m_logbsize = suffix_strtoul(value, &eov, 10);
		} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
			if (!mp->m_logname)
				return ENOMEM;
		} else if (!strcmp(this_char, MNTOPT_MTPT)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			*mtpt = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
			if (!*mtpt)
				return ENOMEM;
		} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
			if (!mp->m_rtname)
				return ENOMEM;
		} else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			iosize = simple_strtoul(value, &eov, 10);
			iosizelog = ffs(iosize) - 1;
		} else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			iosize = suffix_strtoul(value, &eov, 10);
			iosizelog = ffs(iosize) - 1;
		} else if (!strcmp(this_char, MNTOPT_GRPID) ||
			   !strcmp(this_char, MNTOPT_BSDGROUPS)) {
			mp->m_flags |= XFS_MOUNT_GRPID;
		} else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
			   !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
			mp->m_flags &= ~XFS_MOUNT_GRPID;
		} else if (!strcmp(this_char, MNTOPT_WSYNC)) {
			mp->m_flags |= XFS_MOUNT_WSYNC;
		} else if (!strcmp(this_char, MNTOPT_OSYNCISOSYNC)) {
			mp->m_flags |= XFS_MOUNT_OSYNCISOSYNC;
		} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
			mp->m_flags |= XFS_MOUNT_NORECOVERY;
		} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
			mp->m_flags |= XFS_MOUNT_NOALIGN;
		} else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
			mp->m_flags |= XFS_MOUNT_SWALLOC;
		} else if (!strcmp(this_char, MNTOPT_SUNIT)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			dsunit = simple_strtoul(value, &eov, 10);
		} else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
			if (!value || !*value) {
				cmn_err(CE_WARN,
					"XFS: %s option requires an argument",
					this_char);
				return EINVAL;
			}
			dswidth = simple_strtoul(value, &eov, 10);
		} else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
#if !XFS_BIG_INUMS
			cmn_err(CE_WARN,
				"XFS: %s option not allowed on this system",
				this_char);
			return EINVAL;
#endif
		} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
			mp->m_flags |= XFS_MOUNT_NOUUID;
		} else if (!strcmp(this_char, MNTOPT_BARRIER)) {
			mp->m_flags |= XFS_MOUNT_BARRIER;
		} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
			mp->m_flags &= ~XFS_MOUNT_BARRIER;
		} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
			mp->m_flags |= XFS_MOUNT_IKEEP;
		} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
			dmapi_implies_ikeep = 0;
			mp->m_flags &= ~XFS_MOUNT_IKEEP;
		} else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
		} else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
		} else if (!strcmp(this_char, MNTOPT_ATTR2)) {
			mp->m_flags |= XFS_MOUNT_ATTR2;
		} else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
			mp->m_flags &= ~XFS_MOUNT_ATTR2;
			mp->m_flags |= XFS_MOUNT_NOATTR2;
		} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
		} else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
			mp->m_qflags &= ~(XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
					  XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
					  XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
					  XFS_UQUOTA_ENFD | XFS_OQUOTA_ENFD);
		} else if (!strcmp(this_char, MNTOPT_QUOTA) ||
			   !strcmp(this_char, MNTOPT_UQUOTA) ||
			   !strcmp(this_char, MNTOPT_USRQUOTA)) {
			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
					 XFS_UQUOTA_ENFD);
		} else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
			   !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_UQUOTA_ENFD;
		} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
			   !strcmp(this_char, MNTOPT_PRJQUOTA)) {
			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
					 XFS_OQUOTA_ENFD);
		} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_OQUOTA_ENFD;
		} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
			   !strcmp(this_char, MNTOPT_GRPQUOTA)) {
			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
					 XFS_OQUOTA_ENFD);
		} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_OQUOTA_ENFD;
		} else if (!strcmp(this_char, MNTOPT_DMAPI)) {
			mp->m_flags |= XFS_MOUNT_DMAPI;
		} else if (!strcmp(this_char, MNTOPT_XDSM)) {
			mp->m_flags |= XFS_MOUNT_DMAPI;
		} else if (!strcmp(this_char, MNTOPT_DMI)) {
			mp->m_flags |= XFS_MOUNT_DMAPI;
		} else if (!strcmp(this_char, "ihashsize")) {
			cmn_err(CE_WARN,
	"XFS: ihashsize no longer used, option is deprecated.");
		} else if (!strcmp(this_char, "osyncisdsync")) {
			/* no-op, this is now the default */
			cmn_err(CE_WARN,
	"XFS: osyncisdsync is now the default, option is deprecated.");
		} else if (!strcmp(this_char, "irixsgid")) {
			cmn_err(CE_WARN,
	"XFS: irixsgid is now a sysctl(2) variable, option is deprecated.");
		} else {
			cmn_err(CE_WARN,
				"XFS: unknown mount option [%s].", this_char);
			return EINVAL;
		}
	}

	/*
	 * no recovery flag requires a read-only mount
	 */
	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
		cmn_err(CE_WARN, "XFS: no-recovery mounts must be read-only.");
		return EINVAL;
	}

	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
		cmn_err(CE_WARN,
	"XFS: sunit and swidth options incompatible with the noalign option");
		return EINVAL;
	}

#ifndef CONFIG_XFS_QUOTA
	if (XFS_IS_QUOTA_RUNNING(mp)) {
		cmn_err(CE_WARN,
			"XFS: quota support not available in this kernel.");
		return EINVAL;
	}
#endif

	if ((mp->m_qflags & (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE)) &&
	    (mp->m_qflags & (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE))) {
		cmn_err(CE_WARN,
			"XFS: cannot mount with both project and group quota");
		return EINVAL;
	}

	if ((mp->m_flags & XFS_MOUNT_DMAPI) && (!*mtpt || *mtpt[0] == '\0')) {
		printk("XFS: %s option needs the mount point option as well\n",
			MNTOPT_DMAPI);
		return EINVAL;
	}

	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
		cmn_err(CE_WARN,
			"XFS: sunit and swidth must be specified together");
		return EINVAL;
	}

	if (dsunit && (dswidth % dsunit != 0)) {
		cmn_err(CE_WARN,
	"XFS: stripe width (%d) must be a multiple of the stripe unit (%d)",
			dswidth, dsunit);
		return EINVAL;
	}

	/*
	 * Applications using DMI filesystems often expect the
	 * inode generation number to be monotonically increasing.
	 * If we delete inode chunks we break this assumption, so
	 * keep unused inode chunks on disk for DMI filesystems
	 * until we come up with a better solution.
	 * Note that if "ikeep" or "noikeep" mount options are
	 * supplied, then they are honored.
	 */
	if ((mp->m_flags & XFS_MOUNT_DMAPI) && dmapi_implies_ikeep)
		mp->m_flags |= XFS_MOUNT_IKEEP;

done:
	if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) {
		/*
		 * At this point the superblock has not been read
		 * in, therefore we do not know the block size.
		 * Before the mount call ends we will convert
		 * these to FSBs.
		 */
		if (dsunit) {
			mp->m_dalign = dsunit;
			mp->m_flags |= XFS_MOUNT_RETERR;
		}

		if (dswidth)
			mp->m_swidth = dswidth;
	}

	if (mp->m_logbufs != -1 &&
	    mp->m_logbufs != 0 &&
	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
		cmn_err(CE_WARN,
			"XFS: invalid logbufs value: %d [not %d-%d]",
			mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
		return XFS_ERROR(EINVAL);
	}
	if (mp->m_logbsize != -1 &&
	    mp->m_logbsize !=  0 &&
	    (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
	     mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
	     !is_power_of_2(mp->m_logbsize))) {
		cmn_err(CE_WARN,
	"XFS: invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
			mp->m_logbsize);
		return XFS_ERROR(EINVAL);
	}

	mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
	if (!mp->m_fsname)
		return ENOMEM;
	mp->m_fsname_len = strlen(mp->m_fsname) + 1;

	if (iosizelog) {
		if (iosizelog > XFS_MAX_IO_LOG ||
		    iosizelog < XFS_MIN_IO_LOG) {
			cmn_err(CE_WARN,
		"XFS: invalid log iosize: %d [not %d-%d]",
				iosizelog, XFS_MIN_IO_LOG,
				XFS_MAX_IO_LOG);
			return XFS_ERROR(EINVAL);
		}

		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
		mp->m_readio_log = iosizelog;
		mp->m_writeio_log = iosizelog;
	}

	return 0;
}
Example #19
0
static struct dentry *
cifs_do_mount(struct file_system_type *fs_type,
	      int flags, const char *dev_name, void *data)
{
	int rc;
	struct super_block *sb;
	struct cifs_sb_info *cifs_sb;
	struct smb_vol *volume_info;
	struct cifs_mnt_data mnt_data;
	struct dentry *root;

	cFYI(1, "Devname: %s flags: %d ", dev_name, flags);

	rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name);
	if (rc)
		return ERR_PTR(rc);

	cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
	if (cifs_sb == NULL) {
		root = ERR_PTR(-ENOMEM);
		goto out;
	}

	cifs_setup_cifs_sb(volume_info, cifs_sb);

	mnt_data.vol = volume_info;
	mnt_data.cifs_sb = cifs_sb;
	mnt_data.flags = flags;

	sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
	if (IS_ERR(sb)) {
		root = ERR_CAST(sb);
		goto out_cifs_sb;
	}

	if (sb->s_fs_info) {
		cFYI(1, "Use existing superblock");
		goto out_shared;
	}

	/*
	 * Copy mount params for use in submounts. Better to do
	 * the copy here and deal with the error before cleanup gets
	 * complicated post-mount.
	 */
	cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
	if (cifs_sb->mountdata == NULL) {
		root = ERR_PTR(-ENOMEM);
		goto out_super;
	}

	sb->s_flags = flags;
	/* BB should we make this contingent on mount parm? */
	sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
	sb->s_fs_info = cifs_sb;

	rc = cifs_read_super(sb, volume_info, dev_name,
			     flags & MS_SILENT ? 1 : 0);
	if (rc) {
		root = ERR_PTR(rc);
		goto out_super;
	}

	sb->s_flags |= MS_ACTIVE;

	root = cifs_get_root(volume_info, sb);
	if (root == NULL)
		goto out_super;

	cFYI(1, "dentry root is: %p", root);
	goto out;

out_shared:
	root = cifs_get_root(volume_info, sb);
	if (root)
		cFYI(1, "dentry root is: %p", root);
	goto out;

out_super:
	kfree(cifs_sb->mountdata);
	deactivate_locked_super(sb);

out_cifs_sb:
	unload_nls(cifs_sb->local_nls);
	kfree(cifs_sb);

out:
	cifs_cleanup_volume_info(&volume_info);
	return root;
}
Example #20
0
static int
nouveau_bios_shadow(struct nouveau_bios *bios)
{
	struct methods shadow_methods[] = {
#if defined(__powerpc__)
		{ "OpenFirmware", nouveau_bios_shadow_of, true, 0, 0, NULL },
#endif
		{ "PRAMIN", nouveau_bios_shadow_pramin, true, 0, 0, NULL },
		{ "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL },
		{ "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL },
		{ "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL },
		{ "PLATFORM", nouveau_bios_shadow_platform, true, 0, 0, NULL },
		{}
	};
	struct methods *mthd, *best;
	const struct firmware *fw;
	const char *optarg;
	int optlen, ret;
	char *source;

	optarg = nouveau_stropt(nv_device(bios)->cfgopt, "NvBios", &optlen);
	source = optarg ? kstrndup(optarg, optlen, GFP_KERNEL) : NULL;
	if (source) {
		/* try to match one of the built-in methods */
		mthd = shadow_methods;
		do {
			if (strcasecmp(source, mthd->desc))
				continue;
			nv_info(bios, "source: %s\n", mthd->desc);

			mthd->shadow(bios);
			mthd->score = nouveau_bios_score(bios, mthd->rw);
			if (mthd->score) {
				kfree(source);
				return 0;
			}
		} while ((++mthd)->shadow);

		/* attempt to load firmware image */
		ret = request_firmware(&fw, source, &nv_device(bios)->pdev->dev);
		if (ret == 0) {
			bios->size = fw->size;
			bios->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
			release_firmware(fw);

			nv_info(bios, "image: %s\n", source);
			if (nouveau_bios_score(bios, 1)) {
				kfree(source);
				return 0;
			}

			kfree(bios->data);
			bios->data = NULL;
		}

		nv_error(bios, "source \'%s\' invalid\n", source);
		kfree(source);
	}

	mthd = shadow_methods;
	do {
		nv_info(bios, "checking %s for image...\n", mthd->desc);
		mthd->shadow(bios);
		mthd->score = nouveau_bios_score(bios, mthd->rw);
		mthd->size = bios->size;
		mthd->data = bios->data;
		bios->data = NULL;
	} while (mthd->score != 3 && (++mthd)->shadow);

	mthd = shadow_methods;
	best = mthd;
	do {
		if (mthd->score > best->score) {
			kfree(best->data);
			best = mthd;
		}
	} while ((++mthd)->shadow);

	if (best->score) {
		nv_info(bios, "using image from %s\n", best->desc);
		bios->size = best->size;
		bios->data = best->data;
		return 0;
	}

	nv_error(bios, "unable to locate usable image\n");
	return -EINVAL;
}
/*
 * This function fills in xfs_mount_t fields based on mount args.
 * Note: the superblock has _not_ yet been read in.
 *
 * Note that this function leaks the various device name allocations on
 * failure.  The caller takes care of them.
 *
 * *sb is const because this is also used to test options on the remount
 * path, and we don't want this to have any side effects at remount time.
 * Today this function does not change *sb, but just to future-proof...
 */
STATIC int
xfs_parseargs(
	struct xfs_mount	*mp,
	char			*options)
{
	const struct super_block *sb = mp->m_super;
	char			*p;
	substring_t		args[MAX_OPT_ARGS];
	int			dsunit = 0;
	int			dswidth = 0;
	int			iosize = 0;
	__uint8_t		iosizelog = 0;

	/*
	 * set up the mount name first so all the errors will refer to the
	 * correct device.
	 */
	mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
	if (!mp->m_fsname)
		return -ENOMEM;
	mp->m_fsname_len = strlen(mp->m_fsname) + 1;

	/*
	 * Copy binary VFS mount flags we are interested in.
	 */
	if (sb->s_flags & MS_RDONLY)
		mp->m_flags |= XFS_MOUNT_RDONLY;
	if (sb->s_flags & MS_DIRSYNC)
		mp->m_flags |= XFS_MOUNT_DIRSYNC;
	if (sb->s_flags & MS_SYNCHRONOUS)
		mp->m_flags |= XFS_MOUNT_WSYNC;

	/*
	 * Set some default flags that could be cleared by the mount option
	 * parsing.
	 */
	mp->m_flags |= XFS_MOUNT_BARRIER;
	mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;

	/*
	 * These can be overridden by the mount option parsing.
	 */
	mp->m_logbufs = -1;
	mp->m_logbsize = -1;

	if (!options)
		goto done;

	while ((p = strsep(&options, ",")) != NULL) {
		int		token;

		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
		case Opt_logbufs:
			if (match_int(args, &mp->m_logbufs))
				return -EINVAL;
			break;
		case Opt_logbsize:
			if (suffix_kstrtoint(args, 10, &mp->m_logbsize))
				return -EINVAL;
			break;
		case Opt_logdev:
			mp->m_logname = match_strdup(args);
			if (!mp->m_logname)
				return -ENOMEM;
			break;
		case Opt_mtpt:
			xfs_warn(mp, "%s option not allowed on this system", p);
			return -EINVAL;
		case Opt_rtdev:
			mp->m_rtname = match_strdup(args);
			if (!mp->m_rtname)
				return -ENOMEM;
			break;
		case Opt_allocsize:
		case Opt_biosize:
			if (suffix_kstrtoint(args, 10, &iosize))
				return -EINVAL;
			iosizelog = ffs(iosize) - 1;
			break;
		case Opt_grpid:
		case Opt_bsdgroups:
			mp->m_flags |= XFS_MOUNT_GRPID;
			break;
		case Opt_nogrpid:
		case Opt_sysvgroups:
			mp->m_flags &= ~XFS_MOUNT_GRPID;
			break;
		case Opt_wsync:
			mp->m_flags |= XFS_MOUNT_WSYNC;
			break;
		case Opt_norecovery:
			mp->m_flags |= XFS_MOUNT_NORECOVERY;
			break;
		case Opt_noalign:
			mp->m_flags |= XFS_MOUNT_NOALIGN;
			break;
		case Opt_swalloc:
			mp->m_flags |= XFS_MOUNT_SWALLOC;
			break;
		case Opt_sunit:
			if (match_int(args, &dsunit))
				return -EINVAL;
			break;
		case Opt_swidth:
			if (match_int(args, &dswidth))
				return -EINVAL;
			break;
		case Opt_inode32:
			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
			break;
		case Opt_inode64:
			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
			break;
		case Opt_nouuid:
			mp->m_flags |= XFS_MOUNT_NOUUID;
			break;
		case Opt_barrier:
			mp->m_flags |= XFS_MOUNT_BARRIER;
			break;
		case Opt_nobarrier:
			mp->m_flags &= ~XFS_MOUNT_BARRIER;
			break;
		case Opt_ikeep:
			mp->m_flags |= XFS_MOUNT_IKEEP;
			break;
		case Opt_noikeep:
			mp->m_flags &= ~XFS_MOUNT_IKEEP;
			break;
		case Opt_largeio:
			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
			break;
		case Opt_nolargeio:
			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
			break;
		case Opt_attr2:
			mp->m_flags |= XFS_MOUNT_ATTR2;
			break;
		case Opt_noattr2:
			mp->m_flags &= ~XFS_MOUNT_ATTR2;
			mp->m_flags |= XFS_MOUNT_NOATTR2;
			break;
		case Opt_filestreams:
			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
			break;
		case Opt_noquota:
			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
			break;
		case Opt_quota:
		case Opt_uquota:
		case Opt_usrquota:
			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
					 XFS_UQUOTA_ENFD);
			break;
		case Opt_qnoenforce:
		case Opt_uqnoenforce:
			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_UQUOTA_ENFD;
			break;
		case Opt_pquota:
		case Opt_prjquota:
			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
					 XFS_PQUOTA_ENFD);
			break;
		case Opt_pqnoenforce:
			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_PQUOTA_ENFD;
			break;
		case Opt_gquota:
		case Opt_grpquota:
			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
					 XFS_GQUOTA_ENFD);
			break;
		case Opt_gqnoenforce:
			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_GQUOTA_ENFD;
			break;
		case Opt_discard:
			mp->m_flags |= XFS_MOUNT_DISCARD;
			break;
		case Opt_nodiscard:
			mp->m_flags &= ~XFS_MOUNT_DISCARD;
			break;
#ifdef CONFIG_FS_DAX
		case Opt_dax:
			mp->m_flags |= XFS_MOUNT_DAX;
			break;
#endif
		default:
			xfs_warn(mp, "unknown mount option [%s].", p);
			return -EINVAL;
		}
	}

	/*
	 * no recovery flag requires a read-only mount
	 */
	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
		xfs_warn(mp, "no-recovery mounts must be read-only.");
		return -EINVAL;
	}

	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
		xfs_warn(mp,
	"sunit and swidth options incompatible with the noalign option");
		return -EINVAL;
	}

#ifndef CONFIG_XFS_QUOTA
	if (XFS_IS_QUOTA_RUNNING(mp)) {
		xfs_warn(mp, "quota support not available in this kernel.");
		return -EINVAL;
	}
#endif

	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
		xfs_warn(mp, "sunit and swidth must be specified together");
		return -EINVAL;
	}

	if (dsunit && (dswidth % dsunit != 0)) {
		xfs_warn(mp,
	"stripe width (%d) must be a multiple of the stripe unit (%d)",
			dswidth, dsunit);
		return -EINVAL;
	}

done:
	if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
		/*
		 * At this point the superblock has not been read
		 * in, therefore we do not know the block size.
		 * Before the mount call ends we will convert
		 * these to FSBs.
		 */
		mp->m_dalign = dsunit;
		mp->m_swidth = dswidth;
	}

	if (mp->m_logbufs != -1 &&
	    mp->m_logbufs != 0 &&
	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
			mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
		return -EINVAL;
	}
	if (mp->m_logbsize != -1 &&
	    mp->m_logbsize !=  0 &&
	    (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
	     mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
	     !is_power_of_2(mp->m_logbsize))) {
		xfs_warn(mp,
			"invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
			mp->m_logbsize);
		return -EINVAL;
	}

	if (iosizelog) {
		if (iosizelog > XFS_MAX_IO_LOG ||
		    iosizelog < XFS_MIN_IO_LOG) {
			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
				iosizelog, XFS_MIN_IO_LOG,
				XFS_MAX_IO_LOG);
			return -EINVAL;
		}

		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
		mp->m_readio_log = iosizelog;
		mp->m_writeio_log = iosizelog;
	}

	return 0;
}
Example #22
0
static int uinput_setup_device(struct uinput_device *udev,
                               const char __user *buffer, size_t count)
{
    struct uinput_user_dev	*user_dev;
    struct input_dev	*dev;
    int			i;
    int			retval;

    if (count != sizeof(struct uinput_user_dev))
        return -EINVAL;

    if (!udev->dev) {
        retval = uinput_allocate_device(udev);
        if (retval)
            return retval;
    }

    dev = udev->dev;

    user_dev = memdup_user(buffer, sizeof(struct uinput_user_dev));
    if (IS_ERR(user_dev))
        return PTR_ERR(user_dev);

    udev->ff_effects_max = user_dev->ff_effects_max;

    /* Ensure name is filled in */
    if (!user_dev->name[0]) {
        retval = -EINVAL;
        goto exit;
    }

    kfree(dev->name);
    dev->name = kstrndup(user_dev->name, UINPUT_MAX_NAME_SIZE,
                         GFP_KERNEL);
    if (!dev->name) {
        retval = -ENOMEM;
        goto exit;
    }

    dev->id.bustype	= user_dev->id.bustype;
    dev->id.vendor	= user_dev->id.vendor;
    dev->id.product	= user_dev->id.product;
    dev->id.version	= user_dev->id.version;

    for (i = 0; i < ABS_CNT; i++) {
        input_abs_set_max(dev, i, user_dev->absmax[i]);
        input_abs_set_min(dev, i, user_dev->absmin[i]);
        input_abs_set_fuzz(dev, i, user_dev->absfuzz[i]);
        input_abs_set_flat(dev, i, user_dev->absflat[i]);
    }

    /* check if absmin/absmax/absfuzz/absflat are filled as
     * told in Documentation/input/input-programming.txt */
    if (test_bit(EV_ABS, dev->evbit)) {
        retval = uinput_validate_absbits(dev);
        if (retval < 0)
            goto exit;
        if (test_bit(ABS_MT_SLOT, dev->absbit)) {
            int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
            input_mt_init_slots(dev, nslot, 0);
        } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
            input_set_events_per_packet(dev, 60);
        }
    }

    udev->state = UIST_SETUP_COMPLETE;
    retval = count;

exit:
    kfree(user_dev);
    return retval;
}
Example #23
0
static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
{
	char *token, *o = data;
	bool all_ss = false, one_ss = false;
	u16 mask = U16_MAX;
	struct cgroup_subsys *ss;
	int nr_opts = 0;
	int i;

#ifdef CONFIG_CPUSETS
	mask = ~((u16)1 << cpuset_cgrp_id);
#endif

	memset(opts, 0, sizeof(*opts));

	while ((token = strsep(&o, ",")) != NULL) {
		nr_opts++;

		if (!*token)
			return -EINVAL;
		if (!strcmp(token, "none")) {
			/* Explicitly have no subsystems */
			opts->none = true;
			continue;
		}
		if (!strcmp(token, "all")) {
			/* Mutually exclusive option 'all' + subsystem name */
			if (one_ss)
				return -EINVAL;
			all_ss = true;
			continue;
		}
		if (!strcmp(token, "noprefix")) {
			opts->flags |= CGRP_ROOT_NOPREFIX;
			continue;
		}
		if (!strcmp(token, "clone_children")) {
			opts->cpuset_clone_children = true;
			continue;
		}
		if (!strcmp(token, "cpuset_v2_mode")) {
			opts->flags |= CGRP_ROOT_CPUSET_V2_MODE;
			continue;
		}
		if (!strcmp(token, "xattr")) {
			opts->flags |= CGRP_ROOT_XATTR;
			continue;
		}
		if (!strncmp(token, "release_agent=", 14)) {
			/* Specifying two release agents is forbidden */
			if (opts->release_agent)
				return -EINVAL;
			opts->release_agent =
				kstrndup(token + 14, PATH_MAX - 1, GFP_KERNEL);
			if (!opts->release_agent)
				return -ENOMEM;
			continue;
		}
		if (!strncmp(token, "name=", 5)) {
			const char *name = token + 5;

			/* blocked by boot param? */
			if (cgroup_no_v1_named)
				return -ENOENT;
			/* Can't specify an empty name */
			if (!strlen(name))
				return -EINVAL;
			/* Must match [\w.-]+ */
			for (i = 0; i < strlen(name); i++) {
				char c = name[i];
				if (isalnum(c))
					continue;
				if ((c == '.') || (c == '-') || (c == '_'))
					continue;
				return -EINVAL;
			}
			/* Specifying two names is forbidden */
			if (opts->name)
				return -EINVAL;
			opts->name = kstrndup(name,
					      MAX_CGROUP_ROOT_NAMELEN - 1,
					      GFP_KERNEL);
			if (!opts->name)
				return -ENOMEM;

			continue;
		}

		for_each_subsys(ss, i) {
			if (strcmp(token, ss->legacy_name))
				continue;
			if (!cgroup_ssid_enabled(i))
				continue;
			if (cgroup1_ssid_disabled(i))
				continue;

			/* Mutually exclusive option 'all' + subsystem name */
			if (all_ss)
				return -EINVAL;
			opts->subsys_mask |= (1 << i);
			one_ss = true;

			break;
		}
		if (i == CGROUP_SUBSYS_COUNT)
			return -ENOENT;
	}

	/*
	 * If the 'all' option was specified select all the subsystems,
	 * otherwise if 'none', 'name=' and a subsystem name options were
	 * not specified, let's default to 'all'
	 */
	if (all_ss || (!one_ss && !opts->none && !opts->name))
		for_each_subsys(ss, i)
			if (cgroup_ssid_enabled(i) && !cgroup1_ssid_disabled(i))
				opts->subsys_mask |= (1 << i);

	/*
	 * We either have to specify by name or by subsystems. (So all
	 * empty hierarchies must have a name).
	 */
	if (!opts->subsys_mask && !opts->name)
		return -EINVAL;

	/*
	 * Option noprefix was introduced just for backward compatibility
	 * with the old cpuset, so we allow noprefix only if mounting just
	 * the cpuset subsystem.
	 */
	if ((opts->flags & CGRP_ROOT_NOPREFIX) && (opts->subsys_mask & mask))
		return -EINVAL;

	/* Can't specify "none" and some subsystems */
	if (opts->subsys_mask && opts->none)
		return -EINVAL;

	return 0;
}
int gssp_accept_sec_context_upcall(struct net *net,
				struct gssp_upcall_data *data)
{
	struct gssx_ctx ctxh = {
		.state = data->in_handle
	};
	struct gssx_arg_accept_sec_context arg = {
		.input_token = data->in_token,
	};
	struct gssx_ctx rctxh = {
		/*
		 * pass in the max length we expect for each of these
		 * buffers but let the xdr code kmalloc them:
		 */
		.exported_context_token.len = GSSX_max_output_handle_sz,
		.mech.len = GSS_OID_MAX_LEN,
		.src_name.display_name.len = GSSX_max_princ_sz
	};
	struct gssx_res_accept_sec_context res = {
		.context_handle = &rctxh,
		.output_token = &data->out_token
	};
	struct rpc_message msg = {
		.rpc_proc = &gssp_procedures[GSSX_ACCEPT_SEC_CONTEXT],
		.rpc_argp = &arg,
		.rpc_resp = &res,
		.rpc_cred = NULL, /* FIXME ? */
	};
	struct xdr_netobj client_name = { 0 , NULL };
	int ret;

	if (data->in_handle.len != 0)
		arg.context_handle = &ctxh;
	res.output_token->len = GSSX_max_output_token_sz;

	/* use nfs/ for targ_name ? */

	ret = gssp_call(net, &msg);

	/* we need to fetch all data even in case of error so
	 * that we can free special strctures is they have been allocated */
	data->major_status = res.status.major_status;
	data->minor_status = res.status.minor_status;
	if (res.context_handle) {
		data->out_handle = rctxh.exported_context_token;
		data->mech_oid.len = rctxh.mech.len;
		memcpy(data->mech_oid.data, rctxh.mech.data,
						data->mech_oid.len);
		client_name = rctxh.src_name.display_name;
	}

	if (res.options.count == 1) {
		gssx_buffer *value = &res.options.data[0].value;
		/* Currently we only decode CREDS_VALUE, if we add
		 * anything else we'll have to loop and match on the
		 * option name */
		if (value->len == 1) {
			/* steal group info from struct svc_cred */
			data->creds = *(struct svc_cred *)value->data;
			data->found_creds = 1;
		}
		/* whether we use it or not, free data */
		kfree(value->data);
	}

	if (res.options.count != 0) {
		kfree(res.options.data);
	}

	/* convert to GSS_NT_HOSTBASED_SERVICE form and set into creds */
	if (data->found_creds && client_name.data != NULL) {
		char *c;

		data->creds.cr_principal = kstrndup(client_name.data,
						client_name.len, GFP_KERNEL);
		if (data->creds.cr_principal) {
			/* terminate and remove realm part */
			c = strchr(data->creds.cr_principal, '@');
			if (c) {
				*c = '\0';

				/* change service-hostname delimiter */
				c = strchr(data->creds.cr_principal, '/');
				if (c) *c = '@';
			}
			if (!c) {
				/* not a service principal */
				kfree(data->creds.cr_principal);
				data->creds.cr_principal = NULL;
			}
		}
	}
	kfree(client_name.data);

	return ret;
}

void gssp_free_upcall_data(struct gssp_upcall_data *data)
{
	kfree(data->in_handle.data);
	kfree(data->out_handle.data);
	kfree(data->out_token.data);
	kfree(data->mech_oid.data);
	free_svc_cred(&data->creds);
}

/*
 * Initialization stuff
 */

static const struct rpc_version gssp_version1 = {
	.number		= GSSPROXY_VERS_1,
	.nrprocs	= ARRAY_SIZE(gssp_procedures),
	.procs		= gssp_procedures,
};

static const struct rpc_version *gssp_version[] = {
	NULL,
	&gssp_version1,
};

static struct rpc_stat gssp_stats;

static const struct rpc_program gssp_program = {
	.name		= "gssproxy",
	.number		= GSSPROXY_PROGRAM,
	.nrvers		= ARRAY_SIZE(gssp_version),
	.version	= gssp_version,
	.stats		= &gssp_stats,
};
Example #25
0
static struct dentry *
cifs_do_mount(struct file_system_type *fs_type,
	      int flags, const char *dev_name, void *data)
{
	int rc;
	struct super_block *sb;
	struct cifs_sb_info *cifs_sb;
	struct smb_vol *volume_info;
	struct cifs_mnt_data mnt_data;
	struct dentry *root;

	cifs_dbg(FYI, "Devname: %s flags: %d\n", dev_name, flags);

	volume_info = cifs_get_volume_info((char *)data, dev_name);
	if (IS_ERR(volume_info))
		return ERR_CAST(volume_info);

	cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
	if (cifs_sb == NULL) {
		root = ERR_PTR(-ENOMEM);
		goto out_nls;
	}

	cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
	if (cifs_sb->mountdata == NULL) {
		root = ERR_PTR(-ENOMEM);
		goto out_cifs_sb;
	}

	cifs_setup_cifs_sb(volume_info, cifs_sb);

	rc = cifs_mount(cifs_sb, volume_info);
	if (rc) {
		if (!(flags & MS_SILENT))
			cifs_dbg(VFS, "cifs_mount failed w/return code = %d\n",
				 rc);
		root = ERR_PTR(rc);
		goto out_mountdata;
	}

	mnt_data.vol = volume_info;
	mnt_data.cifs_sb = cifs_sb;
	mnt_data.flags = flags;

	/* BB should we make this contingent on mount parm? */
	flags |= MS_NODIRATIME | MS_NOATIME;

	sb = sget(fs_type, cifs_match_super, cifs_set_super, flags, &mnt_data);
	if (IS_ERR(sb)) {
		root = ERR_CAST(sb);
		cifs_umount(cifs_sb);
		goto out;
	}

	if (sb->s_root) {
		cifs_dbg(FYI, "Use existing superblock\n");
		cifs_umount(cifs_sb);
	} else {
		rc = cifs_read_super(sb);
		if (rc) {
			root = ERR_PTR(rc);
			goto out_super;
		}

		sb->s_flags |= MS_ACTIVE;
	}

	root = cifs_get_root(volume_info, sb);
	if (IS_ERR(root))
		goto out_super;

	cifs_dbg(FYI, "dentry root is: %p\n", root);
	goto out;

out_super:
	deactivate_locked_super(sb);
out:
	cifs_cleanup_volume_info(volume_info);
	return root;

out_mountdata:
	kfree(cifs_sb->mountdata);
out_cifs_sb:
	kfree(cifs_sb);
out_nls:
	unload_nls(volume_info->local_nls);
	goto out;
}
Example #26
0
L4_CV static
int l4xfdx_factory_create(struct l4x_fdx_srv_factory_create_data *data,
                          l4_cap_idx_t *client_cap)
{
    struct l4fdx_client *client;
    void *objmem;
    int ret;

    BUG_ON(!irqs_disabled()); /* utcb-data still hot */

    client = kzalloc(sizeof(*client), GFP_ATOMIC);
    if (!client)
        return -ENOMEM;

    ret = -ENOMEM;
    objmem = kmalloc(l4x_fdx_srv_objsize(), GFP_ATOMIC);
    if (!objmem)
        goto out_free_client;

    client->enabled = 1;
    if (data->opt_flags & L4X_FDX_SRV_FACTORY_HAS_UID)
        client->uid = data->uid;
    else
        client->uid = DEFAULT_UID;

    if (data->opt_flags & L4X_FDX_SRV_FACTORY_HAS_GID)
        client->gid = data->gid;
    else
        client->gid = DEFAULT_GID;

    if (data->opt_flags & L4X_FDX_SRV_FACTORY_HAS_OPENFLAGS_MASK)
        client->openflags_mask = data->openflags_mask;
    else
        client->openflags_mask = DEFAULT_OPEN_FLAGS_MASK;

    if (data->opt_flags & L4X_FDX_SRV_FACTORY_HAS_BASEPATH) {
        client->basepath_len = data->basepath_len;
        if (!data->basepath[client->basepath_len - 1])
            --client->basepath_len;
        client->basepath = kstrndup(data->basepath,
                                    client->basepath_len, GFP_ATOMIC);
        if (!client->basepath)
            goto out_free_objmem_and_client_strings;
    }

    if (data->opt_flags & L4X_FDX_SRV_FACTORY_HAS_FILTERPATH) {
        client->filterpath_len = data->filterpath_len;
        if (!data->filterpath[client->filterpath_len - 1])
            --client->filterpath_len;
        client->filterpath = kstrndup(data->filterpath,
                                      client->filterpath_len, GFP_ATOMIC);
        if (!client->filterpath)
            goto out_free_objmem_and_client_strings;
    }

    if (data->opt_flags & L4X_FDX_SRV_FACTORY_HAS_CLIENTNAME) {
        client->capname = kstrndup(data->clientname,
                                   data->clientname_len + 1, GFP_ATOMIC);
        if (!client->capname)
            goto out_free_objmem_and_client_strings;

        client->capname[data->clientname_len] = 0;
    }

    if (data->opt_flags & L4X_FDX_SRV_FACTORY_HAS_FLAG_NOGROW)
        client->flag_nogrow = 1;

    spin_lock_init(&client->req_list_lock);
    INIT_LIST_HEAD(&client->req_list);
    init_waitqueue_head(&client->event);

    INIT_WORK(&client->create_work, create_server);

    client->srv_obj = L4XV_FN(l4fdx_srv_obj,
                              l4x_fdx_srv_create(l4x_cpu_thread_get_cap(0),
                                      &b_ops, client, objmem,
                                      client_cap));

    queue_work(khelper_wq, &client->create_work);

    client->cap = *client_cap;
    INIT_WORK(&client->add_device_work, add_device);
    queue_work(khelper_wq, &client->add_device_work);

    return 0;

out_free_objmem_and_client_strings:
    kfree(objmem);
    kfree(client->basepath);
    kfree(client->filterpath);
    kfree(client->capname);

out_free_client:
    kfree(client);

    return ret;
}
static int __init dm_setup_parse_targets(char *str)
{
	char *next = NULL;
	size_t len = 0;
	struct dm_setup_target **target = NULL;

	/* Targets are defined as per the table format but with a
	 * comma as a newline separator. */
	target = &dm_setup_args.target;
	while (str && *str) {
		*target = kzalloc(sizeof(struct dm_setup_target), GFP_KERNEL);
		if (!*target) {
			DMERR("failed to allocate memory for target %d",
			      dm_setup_args.target_count);
			goto parse_fail;
		}
		dm_setup_args.target_count++;

		(*target)->begin = simple_strtoull(str, &next, 10);
		if (!next || *next != DM_FIELD_SEP) {
			DMERR("failed to parse starting sector for target %d",
			      dm_setup_args.target_count - 1);
			goto parse_fail;
		}
		str = skip_spaces(next + 1);

		(*target)->length = simple_strtoull(str, &next, 10);
		if (!next || *next != DM_FIELD_SEP) {
			DMERR("failed to parse length for target %d",
			      dm_setup_args.target_count - 1);
			goto parse_fail;
		}
		str = skip_spaces(next + 1);

		len = get_dm_option(str, &next, DM_FIELD_SEP);
		if (!len ||
		    !((*target)->type = kstrndup(str, len, GFP_KERNEL))) {
			DMERR("failed to parse type for target %d",
			      dm_setup_args.target_count - 1);
			goto parse_fail;
		}
		str = skip_spaces(next);

		len = get_dm_option(str, &next, DM_LINE_SEP);
		if (!len ||
		    !((*target)->params = kstrndup(str, len, GFP_KERNEL))) {
			DMERR("failed to parse params for target %d",
			      dm_setup_args.target_count - 1);
			goto parse_fail;
		}
		str = skip_spaces(next);

		/* Before moving on, walk through the copied target and
		 * attempt to replace all /dev/xxx with the major:minor number.
		 * It may not be possible to resolve them traditionally at
		 * boot-time. */
		dm_substitute_devices((*target)->params, len);

		target = &((*target)->next);
	}
	DMDEBUG("parsed %d targets", dm_setup_args.target_count);

	return 0;

parse_fail:
	return 1;
}
Example #28
0
ssize_t nd_namespace_store(struct device *dev,
		struct nd_namespace_common **_ndns, const char *buf,
		size_t len)
{
	struct nd_namespace_common *ndns;
	struct device *found;
	char *name;

	if (dev->driver) {
		dev_dbg(dev, "%s: -EBUSY\n", __func__);
		return -EBUSY;
	}

	name = kstrndup(buf, len, GFP_KERNEL);
	if (!name)
		return -ENOMEM;
	strim(name);

	if (strncmp(name, "namespace", 9) == 0 || strcmp(name, "") == 0)
		/* pass */;
	else {
		len = -EINVAL;
		goto out;
	}

	ndns = *_ndns;
	if (strcmp(name, "") == 0) {
		nd_detach_and_reset(dev, _ndns);
		goto out;
	} else if (ndns) {
		dev_dbg(dev, "namespace already set to: %s\n",
				dev_name(&ndns->dev));
		len = -EBUSY;
		goto out;
	}

	found = device_find_child(dev->parent, name, namespace_match);
	if (!found) {
		dev_dbg(dev, "'%s' not found under %s\n", name,
				dev_name(dev->parent));
		len = -ENODEV;
		goto out;
	}

	ndns = to_ndns(found);
	if (__nvdimm_namespace_capacity(ndns) < SZ_16M) {
		dev_dbg(dev, "%s too small to host\n", name);
		len = -ENXIO;
		goto out_attach;
	}

	WARN_ON_ONCE(!is_nvdimm_bus_locked(dev));
	if (!nd_attach_ndns(dev, ndns, _ndns)) {
		dev_dbg(dev, "%s already claimed\n",
				dev_name(&ndns->dev));
		len = -EBUSY;
	}

 out_attach:
	put_device(&ndns->dev); /* from device_find_child */
 out:
	kfree(name);
	return len;
}
Example #29
0
/*
 * This function fills in xfs_mount_t fields based on mount args.
 * Note: the superblock has _not_ yet been read in.
 *
 * Note that this function leaks the various device name allocations on
 * failure.  The caller takes care of them.
 */
STATIC int
xfs_parseargs(
	struct xfs_mount	*mp,
	char			*options)
{
	struct super_block	*sb = mp->m_super;
	char			*this_char, *value;
	int			dsunit = 0;
	int			dswidth = 0;
	int			iosize = 0;
	__uint8_t		iosizelog = 0;

	/*
	 * set up the mount name first so all the errors will refer to the
	 * correct device.
	 */
	mp->m_fsname = kstrndup(sb->s_id, MAXNAMELEN, GFP_KERNEL);
	if (!mp->m_fsname)
		return -ENOMEM;
	mp->m_fsname_len = strlen(mp->m_fsname) + 1;

	/*
	 * Copy binary VFS mount flags we are interested in.
	 */
	if (sb->s_flags & MS_RDONLY)
		mp->m_flags |= XFS_MOUNT_RDONLY;
	if (sb->s_flags & MS_DIRSYNC)
		mp->m_flags |= XFS_MOUNT_DIRSYNC;
	if (sb->s_flags & MS_SYNCHRONOUS)
		mp->m_flags |= XFS_MOUNT_WSYNC;

	/*
	 * Set some default flags that could be cleared by the mount option
	 * parsing.
	 */
	mp->m_flags |= XFS_MOUNT_BARRIER;
	mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;

	/*
	 * These can be overridden by the mount option parsing.
	 */
	mp->m_logbufs = -1;
	mp->m_logbsize = -1;

	if (!options)
		goto done;

	while ((this_char = strsep(&options, ",")) != NULL) {
		if (!*this_char)
			continue;
		if ((value = strchr(this_char, '=')) != NULL)
			*value++ = 0;

		if (!strcmp(this_char, MNTOPT_LOGBUFS)) {
			if (!value || !*value) {
				xfs_warn(mp, "%s option requires an argument",
					this_char);
				return -EINVAL;
			}
			if (kstrtoint(value, 10, &mp->m_logbufs))
				return -EINVAL;
		} else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) {
			if (!value || !*value) {
				xfs_warn(mp, "%s option requires an argument",
					this_char);
				return -EINVAL;
			}
			if (suffix_kstrtoint(value, 10, &mp->m_logbsize))
				return -EINVAL;
		} else if (!strcmp(this_char, MNTOPT_LOGDEV)) {
			if (!value || !*value) {
				xfs_warn(mp, "%s option requires an argument",
					this_char);
				return -EINVAL;
			}
			mp->m_logname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
			if (!mp->m_logname)
				return -ENOMEM;
		} else if (!strcmp(this_char, MNTOPT_MTPT)) {
			xfs_warn(mp, "%s option not allowed on this system",
				this_char);
			return -EINVAL;
		} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
			if (!value || !*value) {
				xfs_warn(mp, "%s option requires an argument",
					this_char);
				return -EINVAL;
			}
			mp->m_rtname = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
			if (!mp->m_rtname)
				return -ENOMEM;
		} else if (!strcmp(this_char, MNTOPT_BIOSIZE)) {
			if (!value || !*value) {
				xfs_warn(mp, "%s option requires an argument",
					this_char);
				return -EINVAL;
			}
			if (kstrtoint(value, 10, &iosize))
				return -EINVAL;
			iosizelog = ffs(iosize) - 1;
		} else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) {
			if (!value || !*value) {
				xfs_warn(mp, "%s option requires an argument",
					this_char);
				return -EINVAL;
			}
			if (suffix_kstrtoint(value, 10, &iosize))
				return -EINVAL;
			iosizelog = ffs(iosize) - 1;
		} else if (!strcmp(this_char, MNTOPT_GRPID) ||
			   !strcmp(this_char, MNTOPT_BSDGROUPS)) {
			mp->m_flags |= XFS_MOUNT_GRPID;
		} else if (!strcmp(this_char, MNTOPT_NOGRPID) ||
			   !strcmp(this_char, MNTOPT_SYSVGROUPS)) {
			mp->m_flags &= ~XFS_MOUNT_GRPID;
		} else if (!strcmp(this_char, MNTOPT_WSYNC)) {
			mp->m_flags |= XFS_MOUNT_WSYNC;
		} else if (!strcmp(this_char, MNTOPT_NORECOVERY)) {
			mp->m_flags |= XFS_MOUNT_NORECOVERY;
		} else if (!strcmp(this_char, MNTOPT_NOALIGN)) {
			mp->m_flags |= XFS_MOUNT_NOALIGN;
		} else if (!strcmp(this_char, MNTOPT_SWALLOC)) {
			mp->m_flags |= XFS_MOUNT_SWALLOC;
		} else if (!strcmp(this_char, MNTOPT_SUNIT)) {
			if (!value || !*value) {
				xfs_warn(mp, "%s option requires an argument",
					this_char);
				return -EINVAL;
			}
			if (kstrtoint(value, 10, &dsunit))
				return -EINVAL;
		} else if (!strcmp(this_char, MNTOPT_SWIDTH)) {
			if (!value || !*value) {
				xfs_warn(mp, "%s option requires an argument",
					this_char);
				return -EINVAL;
			}
			if (kstrtoint(value, 10, &dswidth))
				return -EINVAL;
		} else if (!strcmp(this_char, MNTOPT_32BITINODE)) {
			mp->m_flags |= XFS_MOUNT_SMALL_INUMS;
		} else if (!strcmp(this_char, MNTOPT_64BITINODE)) {
			mp->m_flags &= ~XFS_MOUNT_SMALL_INUMS;
		} else if (!strcmp(this_char, MNTOPT_NOUUID)) {
			mp->m_flags |= XFS_MOUNT_NOUUID;
		} else if (!strcmp(this_char, MNTOPT_BARRIER)) {
			mp->m_flags |= XFS_MOUNT_BARRIER;
		} else if (!strcmp(this_char, MNTOPT_NOBARRIER)) {
			mp->m_flags &= ~XFS_MOUNT_BARRIER;
		} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
			mp->m_flags |= XFS_MOUNT_IKEEP;
		} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
			mp->m_flags &= ~XFS_MOUNT_IKEEP;
		} else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
			mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
		} else if (!strcmp(this_char, MNTOPT_NOLARGEIO)) {
			mp->m_flags |= XFS_MOUNT_COMPAT_IOSIZE;
		} else if (!strcmp(this_char, MNTOPT_ATTR2)) {
			mp->m_flags |= XFS_MOUNT_ATTR2;
		} else if (!strcmp(this_char, MNTOPT_NOATTR2)) {
			mp->m_flags &= ~XFS_MOUNT_ATTR2;
			mp->m_flags |= XFS_MOUNT_NOATTR2;
		} else if (!strcmp(this_char, MNTOPT_FILESTREAM)) {
			mp->m_flags |= XFS_MOUNT_FILESTREAMS;
		} else if (!strcmp(this_char, MNTOPT_NOQUOTA)) {
			mp->m_qflags &= ~XFS_ALL_QUOTA_ACCT;
			mp->m_qflags &= ~XFS_ALL_QUOTA_ENFD;
			mp->m_qflags &= ~XFS_ALL_QUOTA_ACTIVE;
		} else if (!strcmp(this_char, MNTOPT_QUOTA) ||
			   !strcmp(this_char, MNTOPT_UQUOTA) ||
			   !strcmp(this_char, MNTOPT_USRQUOTA)) {
			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE |
					 XFS_UQUOTA_ENFD);
		} else if (!strcmp(this_char, MNTOPT_QUOTANOENF) ||
			   !strcmp(this_char, MNTOPT_UQUOTANOENF)) {
			mp->m_qflags |= (XFS_UQUOTA_ACCT | XFS_UQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_UQUOTA_ENFD;
		} else if (!strcmp(this_char, MNTOPT_PQUOTA) ||
			   !strcmp(this_char, MNTOPT_PRJQUOTA)) {
			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE |
					 XFS_PQUOTA_ENFD);
		} else if (!strcmp(this_char, MNTOPT_PQUOTANOENF)) {
			mp->m_qflags |= (XFS_PQUOTA_ACCT | XFS_PQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_PQUOTA_ENFD;
		} else if (!strcmp(this_char, MNTOPT_GQUOTA) ||
			   !strcmp(this_char, MNTOPT_GRPQUOTA)) {
			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE |
					 XFS_GQUOTA_ENFD);
		} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
			mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
			mp->m_qflags &= ~XFS_GQUOTA_ENFD;
		} else if (!strcmp(this_char, MNTOPT_DISCARD)) {
			mp->m_flags |= XFS_MOUNT_DISCARD;
		} else if (!strcmp(this_char, MNTOPT_NODISCARD)) {
			mp->m_flags &= ~XFS_MOUNT_DISCARD;
		} else {
			xfs_warn(mp, "unknown mount option [%s].", this_char);
			return -EINVAL;
		}
	}

	/*
	 * no recovery flag requires a read-only mount
	 */
	if ((mp->m_flags & XFS_MOUNT_NORECOVERY) &&
	    !(mp->m_flags & XFS_MOUNT_RDONLY)) {
		xfs_warn(mp, "no-recovery mounts must be read-only.");
		return -EINVAL;
	}

	if ((mp->m_flags & XFS_MOUNT_NOALIGN) && (dsunit || dswidth)) {
		xfs_warn(mp,
	"sunit and swidth options incompatible with the noalign option");
		return -EINVAL;
	}

#ifndef CONFIG_XFS_QUOTA
	if (XFS_IS_QUOTA_RUNNING(mp)) {
		xfs_warn(mp, "quota support not available in this kernel.");
		return -EINVAL;
	}
#endif

	if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
		xfs_warn(mp, "sunit and swidth must be specified together");
		return -EINVAL;
	}

	if (dsunit && (dswidth % dsunit != 0)) {
		xfs_warn(mp,
	"stripe width (%d) must be a multiple of the stripe unit (%d)",
			dswidth, dsunit);
		return -EINVAL;
	}

done:
	if (dsunit && !(mp->m_flags & XFS_MOUNT_NOALIGN)) {
		/*
		 * At this point the superblock has not been read
		 * in, therefore we do not know the block size.
		 * Before the mount call ends we will convert
		 * these to FSBs.
		 */
		mp->m_dalign = dsunit;
		mp->m_swidth = dswidth;
	}

	if (mp->m_logbufs != -1 &&
	    mp->m_logbufs != 0 &&
	    (mp->m_logbufs < XLOG_MIN_ICLOGS ||
	     mp->m_logbufs > XLOG_MAX_ICLOGS)) {
		xfs_warn(mp, "invalid logbufs value: %d [not %d-%d]",
			mp->m_logbufs, XLOG_MIN_ICLOGS, XLOG_MAX_ICLOGS);
		return -EINVAL;
	}
	if (mp->m_logbsize != -1 &&
	    mp->m_logbsize !=  0 &&
	    (mp->m_logbsize < XLOG_MIN_RECORD_BSIZE ||
	     mp->m_logbsize > XLOG_MAX_RECORD_BSIZE ||
	     !is_power_of_2(mp->m_logbsize))) {
		xfs_warn(mp,
			"invalid logbufsize: %d [not 16k,32k,64k,128k or 256k]",
			mp->m_logbsize);
		return -EINVAL;
	}

	if (iosizelog) {
		if (iosizelog > XFS_MAX_IO_LOG ||
		    iosizelog < XFS_MIN_IO_LOG) {
			xfs_warn(mp, "invalid log iosize: %d [not %d-%d]",
				iosizelog, XFS_MIN_IO_LOG,
				XFS_MAX_IO_LOG);
			return -EINVAL;
		}

		mp->m_flags |= XFS_MOUNT_DFLT_IOSIZE;
		mp->m_readio_log = iosizelog;
		mp->m_writeio_log = iosizelog;
	}

	return 0;
}
Example #30
0
static
int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info)
{
	int result, ifindex;
	struct wimax_dev *wimax_dev;
	struct device *dev;
	struct nlmsghdr *nlh = info->nlhdr;
	char *pipe_name;
	void *msg_buf;
	size_t msg_len;

	might_sleep();
	d_fnstart(3, NULL, "(skb %p info %p)\n", skb, info);
	result = -ENODEV;
	if (info->attrs[WIMAX_GNL_MSG_IFIDX] == NULL) {
		printk(KERN_ERR "WIMAX_GNL_MSG_FROM_USER: can't find IFIDX "
		       "attribute\n");
		goto error_no_wimax_dev;
	}
	ifindex = nla_get_u32(info->attrs[WIMAX_GNL_MSG_IFIDX]);
	wimax_dev = wimax_dev_get_by_genl_info(info, ifindex);
	if (wimax_dev == NULL)
		goto error_no_wimax_dev;
	dev = wimax_dev_to_dev(wimax_dev);

	/*                  */
	result = -EINVAL;
	if (info->attrs[WIMAX_GNL_MSG_DATA] == NULL) {
		dev_err(dev, "WIMAX_GNL_MSG_FROM_USER: can't find MSG_DATA "
			"attribute\n");
		goto error_no_data;
	}
	msg_buf = nla_data(info->attrs[WIMAX_GNL_MSG_DATA]);
	msg_len = nla_len(info->attrs[WIMAX_GNL_MSG_DATA]);

	if (info->attrs[WIMAX_GNL_MSG_PIPE_NAME] == NULL)
		pipe_name = NULL;
	else {
		struct nlattr *attr = info->attrs[WIMAX_GNL_MSG_PIPE_NAME];
		size_t attr_len = nla_len(attr);
		/*                                               */
		result = -ENOMEM;
		pipe_name = kstrndup(nla_data(attr), attr_len + 1, GFP_KERNEL);
		if (pipe_name == NULL)
			goto error_alloc;
		pipe_name[attr_len] = 0;
	}
	mutex_lock(&wimax_dev->mutex);
	result = wimax_dev_is_ready(wimax_dev);
	if (result == -ENOMEDIUM)
		result = 0;
	if (result < 0)
		goto error_not_ready;
	result = -ENOSYS;
	if (wimax_dev->op_msg_from_user == NULL)
		goto error_noop;

	d_printf(1, dev,
		 "CRX: nlmsghdr len %u type %u flags 0x%04x seq 0x%x pid %u\n",
		 nlh->nlmsg_len, nlh->nlmsg_type, nlh->nlmsg_flags,
		 nlh->nlmsg_seq, nlh->nlmsg_pid);
	d_printf(1, dev, "CRX: wimax message %zu bytes\n", msg_len);
	d_dump(2, dev, msg_buf, msg_len);

	result = wimax_dev->op_msg_from_user(wimax_dev, pipe_name,
					     msg_buf, msg_len, info);
error_noop:
error_not_ready:
	mutex_unlock(&wimax_dev->mutex);
error_alloc:
	kfree(pipe_name);
error_no_data:
	dev_put(wimax_dev->net_dev);
error_no_wimax_dev:
	d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
	return result;
}