~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/fuse/xattr.c

Version: ~ [ linux-5.13-rc1 ] ~ [ linux-5.12.2 ] ~ [ linux-5.11.19 ] ~ [ linux-5.10.35 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.117 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.190 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.232 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.268 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.268 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * FUSE: Filesystem in Userspace
  3  * Copyright (C) 2001-2016  Miklos Szeredi <miklos@szeredi.hu>
  4  *
  5  * This program can be distributed under the terms of the GNU GPL.
  6  * See the file COPYING.
  7  */
  8 
  9 #include "fuse_i.h"
 10 
 11 #include <linux/xattr.h>
 12 #include <linux/posix_acl_xattr.h>
 13 
 14 int fuse_setxattr(struct inode *inode, const char *name, const void *value,
 15                   size_t size, int flags)
 16 {
 17         struct fuse_conn *fc = get_fuse_conn(inode);
 18         FUSE_ARGS(args);
 19         struct fuse_setxattr_in inarg;
 20         int err;
 21 
 22         if (fc->no_setxattr)
 23                 return -EOPNOTSUPP;
 24 
 25         memset(&inarg, 0, sizeof(inarg));
 26         inarg.size = size;
 27         inarg.flags = flags;
 28         args.in.h.opcode = FUSE_SETXATTR;
 29         args.in.h.nodeid = get_node_id(inode);
 30         args.in.numargs = 3;
 31         args.in.args[0].size = sizeof(inarg);
 32         args.in.args[0].value = &inarg;
 33         args.in.args[1].size = strlen(name) + 1;
 34         args.in.args[1].value = name;
 35         args.in.args[2].size = size;
 36         args.in.args[2].value = value;
 37         err = fuse_simple_request(fc, &args);
 38         if (err == -ENOSYS) {
 39                 fc->no_setxattr = 1;
 40                 err = -EOPNOTSUPP;
 41         }
 42         if (!err) {
 43                 fuse_invalidate_attr(inode);
 44                 fuse_update_ctime(inode);
 45         }
 46         return err;
 47 }
 48 
 49 ssize_t fuse_getxattr(struct inode *inode, const char *name, void *value,
 50                       size_t size)
 51 {
 52         struct fuse_conn *fc = get_fuse_conn(inode);
 53         FUSE_ARGS(args);
 54         struct fuse_getxattr_in inarg;
 55         struct fuse_getxattr_out outarg;
 56         ssize_t ret;
 57 
 58         if (fc->no_getxattr)
 59                 return -EOPNOTSUPP;
 60 
 61         memset(&inarg, 0, sizeof(inarg));
 62         inarg.size = size;
 63         args.in.h.opcode = FUSE_GETXATTR;
 64         args.in.h.nodeid = get_node_id(inode);
 65         args.in.numargs = 2;
 66         args.in.args[0].size = sizeof(inarg);
 67         args.in.args[0].value = &inarg;
 68         args.in.args[1].size = strlen(name) + 1;
 69         args.in.args[1].value = name;
 70         /* This is really two different operations rolled into one */
 71         args.out.numargs = 1;
 72         if (size) {
 73                 args.out.argvar = 1;
 74                 args.out.args[0].size = size;
 75                 args.out.args[0].value = value;
 76         } else {
 77                 args.out.args[0].size = sizeof(outarg);
 78                 args.out.args[0].value = &outarg;
 79         }
 80         ret = fuse_simple_request(fc, &args);
 81         if (!ret && !size)
 82                 ret = min_t(ssize_t, outarg.size, XATTR_SIZE_MAX);
 83         if (ret == -ENOSYS) {
 84                 fc->no_getxattr = 1;
 85                 ret = -EOPNOTSUPP;
 86         }
 87         return ret;
 88 }
 89 
 90 static int fuse_verify_xattr_list(char *list, size_t size)
 91 {
 92         size_t origsize = size;
 93 
 94         while (size) {
 95                 size_t thislen = strnlen(list, size);
 96 
 97                 if (!thislen || thislen == size)
 98                         return -EIO;
 99 
100                 size -= thislen + 1;
101                 list += thislen + 1;
102         }
103 
104         return origsize;
105 }
106 
107 ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
108 {
109         struct inode *inode = d_inode(entry);
110         struct fuse_conn *fc = get_fuse_conn(inode);
111         FUSE_ARGS(args);
112         struct fuse_getxattr_in inarg;
113         struct fuse_getxattr_out outarg;
114         ssize_t ret;
115 
116         if (!fuse_allow_current_process(fc))
117                 return -EACCES;
118 
119         if (fc->no_listxattr)
120                 return -EOPNOTSUPP;
121 
122         memset(&inarg, 0, sizeof(inarg));
123         inarg.size = size;
124         args.in.h.opcode = FUSE_LISTXATTR;
125         args.in.h.nodeid = get_node_id(inode);
126         args.in.numargs = 1;
127         args.in.args[0].size = sizeof(inarg);
128         args.in.args[0].value = &inarg;
129         /* This is really two different operations rolled into one */
130         args.out.numargs = 1;
131         if (size) {
132                 args.out.argvar = 1;
133                 args.out.args[0].size = size;
134                 args.out.args[0].value = list;
135         } else {
136                 args.out.args[0].size = sizeof(outarg);
137                 args.out.args[0].value = &outarg;
138         }
139         ret = fuse_simple_request(fc, &args);
140         if (!ret && !size)
141                 ret = min_t(ssize_t, outarg.size, XATTR_LIST_MAX);
142         if (ret > 0 && size)
143                 ret = fuse_verify_xattr_list(list, ret);
144         if (ret == -ENOSYS) {
145                 fc->no_listxattr = 1;
146                 ret = -EOPNOTSUPP;
147         }
148         return ret;
149 }
150 
151 int fuse_removexattr(struct inode *inode, const char *name)
152 {
153         struct fuse_conn *fc = get_fuse_conn(inode);
154         FUSE_ARGS(args);
155         int err;
156 
157         if (fc->no_removexattr)
158                 return -EOPNOTSUPP;
159 
160         args.in.h.opcode = FUSE_REMOVEXATTR;
161         args.in.h.nodeid = get_node_id(inode);
162         args.in.numargs = 1;
163         args.in.args[0].size = strlen(name) + 1;
164         args.in.args[0].value = name;
165         err = fuse_simple_request(fc, &args);
166         if (err == -ENOSYS) {
167                 fc->no_removexattr = 1;
168                 err = -EOPNOTSUPP;
169         }
170         if (!err) {
171                 fuse_invalidate_attr(inode);
172                 fuse_update_ctime(inode);
173         }
174         return err;
175 }
176 
177 static int fuse_xattr_get(const struct xattr_handler *handler,
178                          struct dentry *dentry, struct inode *inode,
179                          const char *name, void *value, size_t size)
180 {
181         return fuse_getxattr(inode, name, value, size);
182 }
183 
184 static int fuse_xattr_set(const struct xattr_handler *handler,
185                           struct dentry *dentry, struct inode *inode,
186                           const char *name, const void *value, size_t size,
187                           int flags)
188 {
189         if (!value)
190                 return fuse_removexattr(inode, name);
191 
192         return fuse_setxattr(inode, name, value, size, flags);
193 }
194 
195 static const struct xattr_handler fuse_xattr_handler = {
196         .prefix = "",
197         .get    = fuse_xattr_get,
198         .set    = fuse_xattr_set,
199 };
200 
201 const struct xattr_handler *fuse_xattr_handlers[] = {
202         &fuse_xattr_handler,
203         NULL
204 };
205 
206 const struct xattr_handler *fuse_acl_xattr_handlers[] = {
207         &posix_acl_access_xattr_handler,
208         &posix_acl_default_xattr_handler,
209         &fuse_xattr_handler,
210         NULL
211 };
212 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp