cregit-Linux how code gets into the kernel

Release 4.11 fs/fuse/xattr.c

Directory: fs/fuse
/*
 * FUSE: Filesystem in Userspace
 * Copyright (C) 2001-2016  Miklos Szeredi <miklos@szeredi.hu>
 *
 * This program can be distributed under the terms of the GNU GPL.
 * See the file COPYING.
 */

#include "fuse_i.h"

#include <linux/xattr.h>
#include <linux/posix_acl_xattr.h>


int fuse_setxattr(struct inode *inode, const char *name, const void *value, size_t size, int flags) { struct fuse_conn *fc = get_fuse_conn(inode); FUSE_ARGS(args); struct fuse_setxattr_in inarg; int err; if (fc->no_setxattr) return -EOPNOTSUPP; memset(&inarg, 0, sizeof(inarg)); inarg.size = size; inarg.flags = flags; args.in.h.opcode = FUSE_SETXATTR; args.in.h.nodeid = get_node_id(inode); args.in.numargs = 3; args.in.args[0].size = sizeof(inarg); args.in.args[0].value = &inarg; args.in.args[1].size = strlen(name) + 1; args.in.args[1].value = name; args.in.args[2].size = size; args.in.args[2].value = value; err = fuse_simple_request(fc, &args); if (err == -ENOSYS) { fc->no_setxattr = 1; err = -EOPNOTSUPP; } if (!err) { fuse_invalidate_attr(inode); fuse_update_ctime(inode); } return err; }

Contributors

PersonTokensPropCommitsCommitProp
Seth Forshee251100.00%1100.00%
Total251100.00%1100.00%


ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value, size_t size) { struct fuse_conn *fc = get_fuse_conn(inode); FUSE_ARGS(args); struct fuse_getxattr_in inarg; struct fuse_getxattr_out outarg; ssize_t ret; if (fc->no_getxattr) return -EOPNOTSUPP; memset(&inarg, 0, sizeof(inarg)); inarg.size = size; args.in.h.opcode = FUSE_GETXATTR; args.in.h.nodeid = get_node_id(inode); args.in.numargs = 2; args.in.args[0].size = sizeof(inarg); args.in.args[0].value = &inarg; args.in.args[1].size = strlen(name) + 1; args.in.args[1].value = name; /* This is really two different operations rolled into one */ args.out.numargs = 1; if (size) { args.out.argvar = 1; args.out.args[0].size = size; args.out.args[0].value = value; } else { args.out.args[0].size = sizeof(outarg); args.out.args[0].value = &outarg; } ret = fuse_simple_request(fc, &args); if (!ret && !size) ret = min_t(ssize_t, outarg.size, XATTR_SIZE_MAX); if (ret == -ENOSYS) { fc->no_getxattr = 1; ret = -EOPNOTSUPP; } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Seth Forshee29897.70%150.00%
Miklos Szeredi72.30%150.00%
Total305100.00%2100.00%


static int fuse_verify_xattr_list(char *list, size_t size) { size_t origsize = size; while (size) { size_t thislen = strnlen(list, size); if (!thislen || thislen == size) return -EIO; size -= thislen + 1; list += thislen + 1; } return origsize; }

Contributors

PersonTokensPropCommitsCommitProp
Seth Forshee62100.00%1100.00%
Total62100.00%1100.00%


ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) { struct inode *inode = d_inode(entry); struct fuse_conn *fc = get_fuse_conn(inode); FUSE_ARGS(args); struct fuse_getxattr_in inarg; struct fuse_getxattr_out outarg; ssize_t ret; if (!fuse_allow_current_process(fc)) return -EACCES; if (fc->no_listxattr) return -EOPNOTSUPP; memset(&inarg, 0, sizeof(inarg)); inarg.size = size; args.in.h.opcode = FUSE_LISTXATTR; args.in.h.nodeid = get_node_id(inode); args.in.numargs = 1; args.in.args[0].size = sizeof(inarg); args.in.args[0].value = &inarg; /* This is really two different operations rolled into one */ args.out.numargs = 1; if (size) { args.out.argvar = 1; args.out.args[0].size = size; args.out.args[0].value = list; } else { args.out.args[0].size = sizeof(outarg); args.out.args[0].value = &outarg; } ret = fuse_simple_request(fc, &args); if (!ret && !size) ret = min_t(ssize_t, outarg.size, XATTR_LIST_MAX); if (ret > 0 && size) ret = fuse_verify_xattr_list(list, ret); if (ret == -ENOSYS) { fc->no_listxattr = 1; ret = -EOPNOTSUPP; } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Seth Forshee30197.73%150.00%
Miklos Szeredi72.27%150.00%
Total308100.00%2100.00%


int fuse_removexattr(struct inode *inode, const char *name) { struct fuse_conn *fc = get_fuse_conn(inode); FUSE_ARGS(args); int err; if (fc->no_removexattr) return -EOPNOTSUPP; args.in.h.opcode = FUSE_REMOVEXATTR; args.in.h.nodeid = get_node_id(inode); args.in.numargs = 1; args.in.args[0].size = strlen(name) + 1; args.in.args[0].value = name; err = fuse_simple_request(fc, &args); if (err == -ENOSYS) { fc->no_removexattr = 1; err = -EOPNOTSUPP; } if (!err) { fuse_invalidate_attr(inode); fuse_update_ctime(inode); } return err; }

Contributors

PersonTokensPropCommitsCommitProp
Seth Forshee155100.00%1100.00%
Total155100.00%1100.00%


static int fuse_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, void *value, size_t size) { return fuse_getxattr(inode, name, value, size); }

Contributors

PersonTokensPropCommitsCommitProp
Seth Forshee46100.00%1100.00%
Total46100.00%1100.00%


static int fuse_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, const void *value, size_t size, int flags) { if (!value) return fuse_removexattr(inode, name); return fuse_setxattr(inode, name, value, size, flags); }

Contributors

PersonTokensPropCommitsCommitProp
Seth Forshee65100.00%1100.00%
Total65100.00%1100.00%

static const struct xattr_handler fuse_xattr_handler = { .prefix = "", .get = fuse_xattr_get, .set = fuse_xattr_set, }; const struct xattr_handler *fuse_xattr_handlers[] = { &fuse_xattr_handler, NULL }; const struct xattr_handler *fuse_acl_xattr_handlers[] = { &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, &fuse_xattr_handler, NULL };

Overall Contributors

PersonTokensPropCommitsCommitProp
Seth Forshee124598.89%266.67%
Miklos Szeredi141.11%133.33%
Total1259100.00%3100.00%
Directory: fs/fuse
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.