Beispiel #1
0
struct fs_ctl*
lu_fsctl_create(struct list_head *conf){
    struct fs_ctl *ctl;
    const char *fs_name, *user_name;

    TRACE("creating fs_ctl");
    
    if(!(ctl = (struct fs_ctl*)malloc(sizeof(struct fs_ctl))))
	return NULL;

    memset(ctl, 0, sizeof(struct fs_ctl));

    ctl->cache = lu_cache_create(conf);
    ctl->cfg = conf;

    if(!(fs_name = lu_opt_getchar(conf, "MOUNT", "fs"))){
	ERROR("you need to specify a file system!");
	free(ctl);
	return NULL;
    }

     if(!(ctl->fs_ops = get_filesystem(ctl, (char*)fs_name))){ 
 	ERROR("unsupported file system: %s", fs_name); 
 	free(ctl); 
 	return NULL; 
     }

    if((user_name = lu_opt_getchar(conf, "MOUNT", "username")))
	strcpy(ctl->cred.user, user_name);

    return ctl;
}
Beispiel #2
0
/**
 * alloc_fs_context - Create a filesystem context.
 * @fs_type: The filesystem type.
 * @reference: The dentry from which this one derives (or NULL)
 * @sb_flags: Filesystem/superblock flags (SB_*)
 * @sb_flags_mask: Applicable members of @sb_flags
 * @purpose: The purpose that this configuration shall be used for.
 *
 * Open a filesystem and create a mount context.  The mount context is
 * initialised with the supplied flags and, if a submount/automount from
 * another superblock (referred to by @reference) is supplied, may have
 * parameters such as namespaces copied across from that superblock.
 */
static struct fs_context *alloc_fs_context(struct file_system_type *fs_type,
				      struct dentry *reference,
				      unsigned int sb_flags,
				      unsigned int sb_flags_mask,
				      enum fs_context_purpose purpose)
{
	int (*init_fs_context)(struct fs_context *);
	struct fs_context *fc;
	int ret = -ENOMEM;

	fc = kzalloc(sizeof(struct fs_context), GFP_KERNEL);
	if (!fc)
		return ERR_PTR(-ENOMEM);

	fc->purpose	= purpose;
	fc->sb_flags	= sb_flags;
	fc->sb_flags_mask = sb_flags_mask;
	fc->fs_type	= get_filesystem(fs_type);
	fc->cred	= get_current_cred();
	fc->net_ns	= get_net(current->nsproxy->net_ns);

	mutex_init(&fc->uapi_mutex);

	switch (purpose) {
	case FS_CONTEXT_FOR_MOUNT:
		fc->user_ns = get_user_ns(fc->cred->user_ns);
		break;
	case FS_CONTEXT_FOR_SUBMOUNT:
		fc->user_ns = get_user_ns(reference->d_sb->s_user_ns);
		break;
	case FS_CONTEXT_FOR_RECONFIGURE:
		/* We don't pin any namespaces as the superblock's
		 * subscriptions cannot be changed at this point.
		 */
		atomic_inc(&reference->d_sb->s_active);
		fc->root = dget(reference);
		break;
	}

	/* TODO: Make all filesystems support this unconditionally */
	init_fs_context = fc->fs_type->init_fs_context;
	if (!init_fs_context)
		init_fs_context = legacy_init_fs_context;

	ret = init_fs_context(fc);
	if (ret < 0)
		goto err_fc;
	fc->need_free = true;
	return fc;

err_fc:
	put_fs_context(fc);
	return ERR_PTR(ret);
}
Beispiel #3
0
nfsstat3 get_fattr(nfs_fh3 object, fattr3 *result) {
	nfsstat3 status = NFS3_OK;
	uint64_t identifier = 0;
	int error = 0;
	const char *path = NULL;
	const kfsfilesystem_t *filesystem = get_filesystem(object, &path, &identifier);
	if (filesystem) {
		dlog("\t%s (path, getattr)", path);
		
		kfsstat_t sbuf = {};
		if (filesystem->stat(path, &sbuf, &error, filesystem->context)) {
			*result = (fattr3){};
			
			if (0) {}
			else if (sbuf.type == KFS_REG) { result->type = NF3REG; }
			else if (sbuf.type == KFS_DIR) { result->type = NF3DIR; }
			else if (sbuf.type == KFS_BLK) { result->type = NF3BLK; }
			else if (sbuf.type == KFS_CHR) { result->type = NF3CHR; }
			else if (sbuf.type == KFS_LNK) { result->type = NF3LNK; }
			else if (sbuf.type == KFS_SOCK) { result->type = NF3SOCK; }
			else if (sbuf.type == KFS_FIFO) { result->type = NF3FIFO; }
			
			if (sbuf.mode & KFS_IRUSR) { result->mode |= NFS_IRUSR; }
			if (sbuf.mode & KFS_IWUSR) { result->mode |= NFS_IWUSR; }
			if (sbuf.mode & KFS_IXUSR) { result->mode |= NFS_IXUSR; }
			if (sbuf.mode & KFS_IRGRP) { result->mode |= NFS_IRGRP; }
			if (sbuf.mode & KFS_IWGRP) { result->mode |= NFS_IWGRP; }
			if (sbuf.mode & KFS_IXGRP) { result->mode |= NFS_IXGRP; }
			if (sbuf.mode & KFS_IROTH) { result->mode |= NFS_IROTH; }
			if (sbuf.mode & KFS_IWOTH) { result->mode |= NFS_IWOTH; }
			if (sbuf.mode & KFS_IXOTH) { result->mode |= NFS_IXOTH; }
			
			result->nlink = 1;
			result->uid = getuid();
			result->gid = getgid();
			result->size = sbuf.size;
			result->used = sbuf.used;
			result->rdev = (specdata3){ 0, 0 };
			result->fsid = 0;
			result->fileid = kfs_fileid(identifier, path);
			result->atime = (nfstime3){ sbuf.atime.sec, sbuf.atime.nsec };
			result->mtime = (nfstime3){ sbuf.mtime.sec, sbuf.mtime.nsec };
			result->ctime = (nfstime3){ sbuf.ctime.sec, sbuf.ctime.nsec };
		} else { // stat failed
			status = convert_status(error, NFS3ERR_NOENT);
		}
	} else { // no filesystem
		status = NFS3ERR_BADHANDLE;
	}

	return status;
}
Beispiel #4
0
nfsstat3 set_fattr(nfs_fh3 object, const sattr3 *attrs) {
	nfsstat3 status = NFS3_OK;
	int error = 0;
	const char *path = NULL;
	const kfsfilesystem_t *filesystem = get_filesystem(object, &path, NULL);
	if (filesystem) {
		dlog("\t%s (path, setattr)", path);

		// check for resize
		if (status == NFS3_OK && attrs->size.set_it) {
			if (!filesystem->truncate(path, attrs->size.set_size3_u.size, &error, filesystem->context)) {
				status = convert_status(error, NFS3ERR_NOENT); // truncate failed
			}
		}

		// check for mode change
		if (status == NFS3_OK && attrs->mode.set_it) {
			kfsmode_t mode = 0;
			if (attrs->mode.set_mode3_u.mode & NFS_IRUSR) { mode |= KFS_IRUSR; }
			if (attrs->mode.set_mode3_u.mode & NFS_IWUSR) { mode |= KFS_IWUSR; }
			if (attrs->mode.set_mode3_u.mode & NFS_IXUSR) { mode |= KFS_IXUSR; }
			if (attrs->mode.set_mode3_u.mode & NFS_IRGRP) { mode |= KFS_IRGRP; }
			if (attrs->mode.set_mode3_u.mode & NFS_IWGRP) { mode |= KFS_IWGRP; }
			if (attrs->mode.set_mode3_u.mode & NFS_IXGRP) { mode |= KFS_IXGRP; }
			if (attrs->mode.set_mode3_u.mode & NFS_IROTH) { mode |= KFS_IROTH; }
			if (attrs->mode.set_mode3_u.mode & NFS_IWOTH) { mode |= KFS_IWOTH; }
			if (attrs->mode.set_mode3_u.mode & NFS_IXOTH) { mode |= KFS_IXOTH; }
			
			if (!filesystem->chmod(path, mode, &error, filesystem->context)) {
				status = convert_status(error, NFS3ERR_NOENT); // chmod failed
			}
		}
		
		// set times
		if (status == NFS3_OK && (attrs->atime.set_it || attrs->mtime.set_it)) {
			kfstime_t *atime = attrs->atime.set_it ? &(kfstime_t){
				.sec = attrs->atime.set_atime_u.atime.seconds,
				.nsec = attrs->atime.set_atime_u.atime.nseconds
			} : NULL;
			kfstime_t *mtime = attrs->mtime.set_it ? &(kfstime_t){
				.sec = attrs->mtime.set_mtime_u.mtime.seconds,
				.nsec = attrs->mtime.set_mtime_u.mtime.nseconds
			} : NULL;
Beispiel #5
0
/**
 * vfs_dup_fc_config: Duplicate a filesystem context.
 * @src_fc: The context to copy.
 */
struct fs_context *vfs_dup_fs_context(struct fs_context *src_fc)
{
	struct fs_context *fc;
	int ret;

	if (!src_fc->ops->dup)
		return ERR_PTR(-EOPNOTSUPP);

	fc = kmemdup(src_fc, sizeof(struct fs_context), GFP_KERNEL);
	if (!fc)
		return ERR_PTR(-ENOMEM);

	mutex_init(&fc->uapi_mutex);

	fc->fs_private	= NULL;
	fc->s_fs_info	= NULL;
	fc->source	= NULL;
	fc->security	= NULL;
	get_filesystem(fc->fs_type);
	get_net(fc->net_ns);
	get_user_ns(fc->user_ns);
	get_cred(fc->cred);
	if (fc->log)
		refcount_inc(&fc->log->usage);

	/* Can't call put until we've called ->dup */
	ret = fc->ops->dup(fc, src_fc);
	if (ret < 0)
		goto err_fc;

	ret = security_fs_context_dup(fc, src_fc);
	if (ret < 0)
		goto err_fc;
	return fc;

err_fc:
	put_fs_context(fc);
	return ERR_PTR(ret);
}