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

TOMOYO Linux Cross Reference
Linux/io_uring/xattr.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /io_uring/xattr.c (Architecture m68k) and /io_uring/xattr.c (Architecture alpha)


  1 // SPDX-License-Identifier: GPL-2.0                 1 // SPDX-License-Identifier: GPL-2.0
  2 #include <linux/kernel.h>                           2 #include <linux/kernel.h>
  3 #include <linux/errno.h>                            3 #include <linux/errno.h>
  4 #include <linux/fs.h>                               4 #include <linux/fs.h>
  5 #include <linux/file.h>                             5 #include <linux/file.h>
  6 #include <linux/mm.h>                               6 #include <linux/mm.h>
  7 #include <linux/slab.h>                             7 #include <linux/slab.h>
  8 #include <linux/namei.h>                            8 #include <linux/namei.h>
  9 #include <linux/io_uring.h>                         9 #include <linux/io_uring.h>
 10 #include <linux/xattr.h>                           10 #include <linux/xattr.h>
 11                                                    11 
 12 #include <uapi/linux/io_uring.h>                   12 #include <uapi/linux/io_uring.h>
 13                                                    13 
 14 #include "../fs/internal.h"                        14 #include "../fs/internal.h"
 15                                                    15 
 16 #include "io_uring.h"                              16 #include "io_uring.h"
 17 #include "xattr.h"                                 17 #include "xattr.h"
 18                                                    18 
 19 struct io_xattr {                                  19 struct io_xattr {
 20         struct file                     *file;     20         struct file                     *file;
 21         struct xattr_ctx                ctx;       21         struct xattr_ctx                ctx;
 22         struct filename                 *filen     22         struct filename                 *filename;
 23 };                                                 23 };
 24                                                    24 
 25 void io_xattr_cleanup(struct io_kiocb *req)        25 void io_xattr_cleanup(struct io_kiocb *req)
 26 {                                                  26 {
 27         struct io_xattr *ix = io_kiocb_to_cmd(     27         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
 28                                                    28 
 29         if (ix->filename)                          29         if (ix->filename)
 30                 putname(ix->filename);             30                 putname(ix->filename);
 31                                                    31 
 32         kfree(ix->ctx.kname);                      32         kfree(ix->ctx.kname);
 33         kvfree(ix->ctx.kvalue);                    33         kvfree(ix->ctx.kvalue);
 34 }                                                  34 }
 35                                                    35 
 36 static void io_xattr_finish(struct io_kiocb *r     36 static void io_xattr_finish(struct io_kiocb *req, int ret)
 37 {                                                  37 {
 38         req->flags &= ~REQ_F_NEED_CLEANUP;         38         req->flags &= ~REQ_F_NEED_CLEANUP;
 39                                                    39 
 40         io_xattr_cleanup(req);                     40         io_xattr_cleanup(req);
 41         io_req_set_res(req, ret, 0);               41         io_req_set_res(req, ret, 0);
 42 }                                                  42 }
 43                                                    43 
 44 static int __io_getxattr_prep(struct io_kiocb      44 static int __io_getxattr_prep(struct io_kiocb *req,
 45                               const struct io_     45                               const struct io_uring_sqe *sqe)
 46 {                                                  46 {
 47         struct io_xattr *ix = io_kiocb_to_cmd(     47         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
 48         const char __user *name;                   48         const char __user *name;
 49         int ret;                                   49         int ret;
 50                                                    50 
 51         if (unlikely(req->flags & REQ_F_FIXED_     51         if (unlikely(req->flags & REQ_F_FIXED_FILE))
 52                 return -EBADF;                     52                 return -EBADF;
 53                                                    53 
 54         ix->filename = NULL;                       54         ix->filename = NULL;
 55         ix->ctx.kvalue = NULL;                     55         ix->ctx.kvalue = NULL;
 56         name = u64_to_user_ptr(READ_ONCE(sqe->     56         name = u64_to_user_ptr(READ_ONCE(sqe->addr));
 57         ix->ctx.cvalue = u64_to_user_ptr(READ_     57         ix->ctx.cvalue = u64_to_user_ptr(READ_ONCE(sqe->addr2));
 58         ix->ctx.size = READ_ONCE(sqe->len);        58         ix->ctx.size = READ_ONCE(sqe->len);
 59         ix->ctx.flags = READ_ONCE(sqe->xattr_f     59         ix->ctx.flags = READ_ONCE(sqe->xattr_flags);
 60                                                    60 
 61         if (ix->ctx.flags)                         61         if (ix->ctx.flags)
 62                 return -EINVAL;                    62                 return -EINVAL;
 63                                                    63 
 64         ix->ctx.kname = kmalloc(sizeof(*ix->ct     64         ix->ctx.kname = kmalloc(sizeof(*ix->ctx.kname), GFP_KERNEL);
 65         if (!ix->ctx.kname)                        65         if (!ix->ctx.kname)
 66                 return -ENOMEM;                    66                 return -ENOMEM;
 67                                                    67 
 68         ret = strncpy_from_user(ix->ctx.kname-     68         ret = strncpy_from_user(ix->ctx.kname->name, name,
 69                                 sizeof(ix->ctx     69                                 sizeof(ix->ctx.kname->name));
 70         if (!ret || ret == sizeof(ix->ctx.knam     70         if (!ret || ret == sizeof(ix->ctx.kname->name))
 71                 ret = -ERANGE;                     71                 ret = -ERANGE;
 72         if (ret < 0) {                             72         if (ret < 0) {
 73                 kfree(ix->ctx.kname);              73                 kfree(ix->ctx.kname);
 74                 return ret;                        74                 return ret;
 75         }                                          75         }
 76                                                    76 
 77         req->flags |= REQ_F_NEED_CLEANUP;          77         req->flags |= REQ_F_NEED_CLEANUP;
 78         req->flags |= REQ_F_FORCE_ASYNC;           78         req->flags |= REQ_F_FORCE_ASYNC;
 79         return 0;                                  79         return 0;
 80 }                                                  80 }
 81                                                    81 
 82 int io_fgetxattr_prep(struct io_kiocb *req, co     82 int io_fgetxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 83 {                                                  83 {
 84         return __io_getxattr_prep(req, sqe);       84         return __io_getxattr_prep(req, sqe);
 85 }                                                  85 }
 86                                                    86 
 87 int io_getxattr_prep(struct io_kiocb *req, con     87 int io_getxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 88 {                                                  88 {
 89         struct io_xattr *ix = io_kiocb_to_cmd(     89         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
 90         const char __user *path;                   90         const char __user *path;
 91         int ret;                                   91         int ret;
 92                                                    92 
 93         ret = __io_getxattr_prep(req, sqe);        93         ret = __io_getxattr_prep(req, sqe);
 94         if (ret)                                   94         if (ret)
 95                 return ret;                        95                 return ret;
 96                                                    96 
 97         path = u64_to_user_ptr(READ_ONCE(sqe->     97         path = u64_to_user_ptr(READ_ONCE(sqe->addr3));
 98                                                    98 
 99         ix->filename = getname_flags(path, LOO     99         ix->filename = getname_flags(path, LOOKUP_FOLLOW);
100         if (IS_ERR(ix->filename)) {               100         if (IS_ERR(ix->filename)) {
101                 ret = PTR_ERR(ix->filename);      101                 ret = PTR_ERR(ix->filename);
102                 ix->filename = NULL;              102                 ix->filename = NULL;
103         }                                         103         }
104                                                   104 
105         return ret;                               105         return ret;
106 }                                                 106 }
107                                                   107 
108 int io_fgetxattr(struct io_kiocb *req, unsigne    108 int io_fgetxattr(struct io_kiocb *req, unsigned int issue_flags)
109 {                                                 109 {
110         struct io_xattr *ix = io_kiocb_to_cmd(    110         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
111         int ret;                                  111         int ret;
112                                                   112 
113         WARN_ON_ONCE(issue_flags & IO_URING_F_    113         WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
114                                                   114 
115         ret = do_getxattr(file_mnt_idmap(req->    115         ret = do_getxattr(file_mnt_idmap(req->file),
116                         req->file->f_path.dent    116                         req->file->f_path.dentry,
117                         &ix->ctx);                117                         &ix->ctx);
118                                                   118 
119         io_xattr_finish(req, ret);                119         io_xattr_finish(req, ret);
120         return IOU_OK;                            120         return IOU_OK;
121 }                                                 121 }
122                                                   122 
123 int io_getxattr(struct io_kiocb *req, unsigned    123 int io_getxattr(struct io_kiocb *req, unsigned int issue_flags)
124 {                                                 124 {
125         struct io_xattr *ix = io_kiocb_to_cmd(    125         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
126         unsigned int lookup_flags = LOOKUP_FOL    126         unsigned int lookup_flags = LOOKUP_FOLLOW;
127         struct path path;                         127         struct path path;
128         int ret;                                  128         int ret;
129                                                   129 
130         WARN_ON_ONCE(issue_flags & IO_URING_F_    130         WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
131                                                   131 
132 retry:                                            132 retry:
133         ret = filename_lookup(AT_FDCWD, ix->fi    133         ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL);
134         if (!ret) {                               134         if (!ret) {
135                 ret = do_getxattr(mnt_idmap(pa    135                 ret = do_getxattr(mnt_idmap(path.mnt), path.dentry, &ix->ctx);
136                                                   136 
137                 path_put(&path);                  137                 path_put(&path);
138                 if (retry_estale(ret, lookup_f    138                 if (retry_estale(ret, lookup_flags)) {
139                         lookup_flags |= LOOKUP    139                         lookup_flags |= LOOKUP_REVAL;
140                         goto retry;               140                         goto retry;
141                 }                                 141                 }
142         }                                         142         }
143                                                   143 
144         io_xattr_finish(req, ret);                144         io_xattr_finish(req, ret);
145         return IOU_OK;                            145         return IOU_OK;
146 }                                                 146 }
147                                                   147 
148 static int __io_setxattr_prep(struct io_kiocb     148 static int __io_setxattr_prep(struct io_kiocb *req,
149                         const struct io_uring_    149                         const struct io_uring_sqe *sqe)
150 {                                                 150 {
151         struct io_xattr *ix = io_kiocb_to_cmd(    151         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
152         const char __user *name;                  152         const char __user *name;
153         int ret;                                  153         int ret;
154                                                   154 
155         if (unlikely(req->flags & REQ_F_FIXED_    155         if (unlikely(req->flags & REQ_F_FIXED_FILE))
156                 return -EBADF;                    156                 return -EBADF;
157                                                   157 
158         ix->filename = NULL;                      158         ix->filename = NULL;
159         name = u64_to_user_ptr(READ_ONCE(sqe->    159         name = u64_to_user_ptr(READ_ONCE(sqe->addr));
160         ix->ctx.cvalue = u64_to_user_ptr(READ_    160         ix->ctx.cvalue = u64_to_user_ptr(READ_ONCE(sqe->addr2));
161         ix->ctx.kvalue = NULL;                    161         ix->ctx.kvalue = NULL;
162         ix->ctx.size = READ_ONCE(sqe->len);       162         ix->ctx.size = READ_ONCE(sqe->len);
163         ix->ctx.flags = READ_ONCE(sqe->xattr_f    163         ix->ctx.flags = READ_ONCE(sqe->xattr_flags);
164                                                   164 
165         ix->ctx.kname = kmalloc(sizeof(*ix->ct    165         ix->ctx.kname = kmalloc(sizeof(*ix->ctx.kname), GFP_KERNEL);
166         if (!ix->ctx.kname)                       166         if (!ix->ctx.kname)
167                 return -ENOMEM;                   167                 return -ENOMEM;
168                                                   168 
169         ret = setxattr_copy(name, &ix->ctx);      169         ret = setxattr_copy(name, &ix->ctx);
170         if (ret) {                                170         if (ret) {
171                 kfree(ix->ctx.kname);             171                 kfree(ix->ctx.kname);
172                 return ret;                       172                 return ret;
173         }                                         173         }
174                                                   174 
175         req->flags |= REQ_F_NEED_CLEANUP;         175         req->flags |= REQ_F_NEED_CLEANUP;
176         req->flags |= REQ_F_FORCE_ASYNC;          176         req->flags |= REQ_F_FORCE_ASYNC;
177         return 0;                                 177         return 0;
178 }                                                 178 }
179                                                   179 
180 int io_setxattr_prep(struct io_kiocb *req, con    180 int io_setxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
181 {                                                 181 {
182         struct io_xattr *ix = io_kiocb_to_cmd(    182         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
183         const char __user *path;                  183         const char __user *path;
184         int ret;                                  184         int ret;
185                                                   185 
186         ret = __io_setxattr_prep(req, sqe);       186         ret = __io_setxattr_prep(req, sqe);
187         if (ret)                                  187         if (ret)
188                 return ret;                       188                 return ret;
189                                                   189 
190         path = u64_to_user_ptr(READ_ONCE(sqe->    190         path = u64_to_user_ptr(READ_ONCE(sqe->addr3));
191                                                   191 
192         ix->filename = getname_flags(path, LOO    192         ix->filename = getname_flags(path, LOOKUP_FOLLOW);
193         if (IS_ERR(ix->filename)) {               193         if (IS_ERR(ix->filename)) {
194                 ret = PTR_ERR(ix->filename);      194                 ret = PTR_ERR(ix->filename);
195                 ix->filename = NULL;              195                 ix->filename = NULL;
196         }                                         196         }
197                                                   197 
198         return ret;                               198         return ret;
199 }                                                 199 }
200                                                   200 
201 int io_fsetxattr_prep(struct io_kiocb *req, co    201 int io_fsetxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
202 {                                                 202 {
203         return __io_setxattr_prep(req, sqe);      203         return __io_setxattr_prep(req, sqe);
204 }                                                 204 }
205                                                   205 
206 static int __io_setxattr(struct io_kiocb *req,    206 static int __io_setxattr(struct io_kiocb *req, unsigned int issue_flags,
207                         const struct path *pat    207                         const struct path *path)
208 {                                                 208 {
209         struct io_xattr *ix = io_kiocb_to_cmd(    209         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
210         int ret;                                  210         int ret;
211                                                   211 
212         ret = mnt_want_write(path->mnt);          212         ret = mnt_want_write(path->mnt);
213         if (!ret) {                               213         if (!ret) {
214                 ret = do_setxattr(mnt_idmap(pa    214                 ret = do_setxattr(mnt_idmap(path->mnt), path->dentry, &ix->ctx);
215                 mnt_drop_write(path->mnt);        215                 mnt_drop_write(path->mnt);
216         }                                         216         }
217                                                   217 
218         return ret;                               218         return ret;
219 }                                                 219 }
220                                                   220 
221 int io_fsetxattr(struct io_kiocb *req, unsigne    221 int io_fsetxattr(struct io_kiocb *req, unsigned int issue_flags)
222 {                                                 222 {
223         int ret;                                  223         int ret;
224                                                   224 
225         WARN_ON_ONCE(issue_flags & IO_URING_F_    225         WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
226                                                   226 
227         ret = __io_setxattr(req, issue_flags,     227         ret = __io_setxattr(req, issue_flags, &req->file->f_path);
228         io_xattr_finish(req, ret);                228         io_xattr_finish(req, ret);
229         return IOU_OK;                            229         return IOU_OK;
230 }                                                 230 }
231                                                   231 
232 int io_setxattr(struct io_kiocb *req, unsigned    232 int io_setxattr(struct io_kiocb *req, unsigned int issue_flags)
233 {                                                 233 {
234         struct io_xattr *ix = io_kiocb_to_cmd(    234         struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
235         unsigned int lookup_flags = LOOKUP_FOL    235         unsigned int lookup_flags = LOOKUP_FOLLOW;
236         struct path path;                         236         struct path path;
237         int ret;                                  237         int ret;
238                                                   238 
239         WARN_ON_ONCE(issue_flags & IO_URING_F_    239         WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
240                                                   240 
241 retry:                                            241 retry:
242         ret = filename_lookup(AT_FDCWD, ix->fi    242         ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL);
243         if (!ret) {                               243         if (!ret) {
244                 ret = __io_setxattr(req, issue    244                 ret = __io_setxattr(req, issue_flags, &path);
245                 path_put(&path);                  245                 path_put(&path);
246                 if (retry_estale(ret, lookup_f    246                 if (retry_estale(ret, lookup_flags)) {
247                         lookup_flags |= LOOKUP    247                         lookup_flags |= LOOKUP_REVAL;
248                         goto retry;               248                         goto retry;
249                 }                                 249                 }
250         }                                         250         }
251                                                   251 
252         io_xattr_finish(req, ret);                252         io_xattr_finish(req, ret);
253         return IOU_OK;                            253         return IOU_OK;
254 }                                                 254 }
255                                                   255 

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php