Skip to content

Commit 66d7ac6

Browse files
author
Al Viro
committed
replace do_setxattr() with saner helpers.
io_uring setxattr logics duplicates stuff from fs/xattr.c; provide saner helpers (filename_setxattr() and file_setxattr() resp.) and use them. NB: putname(ERR_PTR()) is a no-op Signed-off-by: Al Viro <[email protected]>
1 parent a10c4c5 commit 66d7ac6

File tree

3 files changed

+54
-62
lines changed

3 files changed

+54
-62
lines changed

fs/internal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,10 +285,10 @@ ssize_t do_getxattr(struct mnt_idmap *idmap,
285285
struct dentry *d,
286286
struct kernel_xattr_ctx *ctx);
287287

288+
int file_setxattr(struct file *file, struct kernel_xattr_ctx *ctx);
289+
int filename_setxattr(int dfd, struct filename *filename,
290+
unsigned int lookup_flags, struct kernel_xattr_ctx *ctx);
288291
int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx);
289-
int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
290-
struct kernel_xattr_ctx *ctx);
291-
292292
int import_xattr_name(struct xattr_name *kname, const char __user *name);
293293

294294
int may_write_xattr(struct mnt_idmap *idmap, struct inode *inode);

fs/xattr.c

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ int setxattr_copy(const char __user *name, struct kernel_xattr_ctx *ctx)
626626
return error;
627627
}
628628

629-
int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
629+
static int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
630630
struct kernel_xattr_ctx *ctx)
631631
{
632632
if (is_posix_acl_xattr(ctx->kname->name))
@@ -637,32 +637,32 @@ int do_setxattr(struct mnt_idmap *idmap, struct dentry *dentry,
637637
ctx->kvalue, ctx->size, ctx->flags);
638638
}
639639

640-
static int path_setxattr(const char __user *pathname,
641-
const char __user *name, const void __user *value,
642-
size_t size, int flags, unsigned int lookup_flags)
640+
int file_setxattr(struct file *f, struct kernel_xattr_ctx *ctx)
641+
{
642+
int error = mnt_want_write_file(f);
643+
644+
if (!error) {
645+
audit_file(f);
646+
error = do_setxattr(file_mnt_idmap(f), f->f_path.dentry, ctx);
647+
mnt_drop_write_file(f);
648+
}
649+
return error;
650+
}
651+
652+
/* unconditionally consumes filename */
653+
int filename_setxattr(int dfd, struct filename *filename,
654+
unsigned int lookup_flags, struct kernel_xattr_ctx *ctx)
643655
{
644-
struct xattr_name kname;
645-
struct kernel_xattr_ctx ctx = {
646-
.cvalue = value,
647-
.kvalue = NULL,
648-
.size = size,
649-
.kname = &kname,
650-
.flags = flags,
651-
};
652656
struct path path;
653657
int error;
654658

655-
error = setxattr_copy(name, &ctx);
656-
if (error)
657-
return error;
658-
659659
retry:
660-
error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
660+
error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);
661661
if (error)
662662
goto out;
663663
error = mnt_want_write(path.mnt);
664664
if (!error) {
665-
error = do_setxattr(mnt_idmap(path.mnt), path.dentry, &ctx);
665+
error = do_setxattr(mnt_idmap(path.mnt), path.dentry, ctx);
666666
mnt_drop_write(path.mnt);
667667
}
668668
path_put(&path);
@@ -672,6 +672,30 @@ static int path_setxattr(const char __user *pathname,
672672
}
673673

674674
out:
675+
putname(filename);
676+
return error;
677+
}
678+
679+
static int path_setxattr(const char __user *pathname,
680+
const char __user *name, const void __user *value,
681+
size_t size, int flags, unsigned int lookup_flags)
682+
{
683+
struct xattr_name kname;
684+
struct kernel_xattr_ctx ctx = {
685+
.cvalue = value,
686+
.kvalue = NULL,
687+
.size = size,
688+
.kname = &kname,
689+
.flags = flags,
690+
};
691+
int error;
692+
693+
error = setxattr_copy(name, &ctx);
694+
if (error)
695+
return error;
696+
697+
error = filename_setxattr(AT_FDCWD, getname(pathname), lookup_flags,
698+
&ctx);
675699
kvfree(ctx.kvalue);
676700
return error;
677701
}
@@ -707,17 +731,12 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name,
707731

708732
if (fd_empty(f))
709733
return -EBADF;
710-
audit_file(fd_file(f));
734+
711735
error = setxattr_copy(name, &ctx);
712736
if (error)
713737
return error;
714738

715-
error = mnt_want_write_file(fd_file(f));
716-
if (!error) {
717-
error = do_setxattr(file_mnt_idmap(fd_file(f)),
718-
fd_file(f)->f_path.dentry, &ctx);
719-
mnt_drop_write_file(fd_file(f));
720-
}
739+
error = file_setxattr(fd_file(f), &ctx);
721740
kvfree(ctx.kvalue);
722741
return error;
723742
}

io_uring/xattr.c

Lines changed: 7 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -187,65 +187,38 @@ int io_setxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
187187
path = u64_to_user_ptr(READ_ONCE(sqe->addr3));
188188

189189
ix->filename = getname(path);
190-
if (IS_ERR(ix->filename)) {
191-
ret = PTR_ERR(ix->filename);
192-
ix->filename = NULL;
193-
}
190+
if (IS_ERR(ix->filename))
191+
return PTR_ERR(ix->filename);
194192

195-
return ret;
193+
return 0;
196194
}
197195

198196
int io_fsetxattr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
199197
{
200198
return __io_setxattr_prep(req, sqe);
201199
}
202200

203-
static int __io_setxattr(struct io_kiocb *req, unsigned int issue_flags,
204-
const struct path *path)
205-
{
206-
struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
207-
int ret;
208-
209-
ret = mnt_want_write(path->mnt);
210-
if (!ret) {
211-
ret = do_setxattr(mnt_idmap(path->mnt), path->dentry, &ix->ctx);
212-
mnt_drop_write(path->mnt);
213-
}
214-
215-
return ret;
216-
}
217-
218201
int io_fsetxattr(struct io_kiocb *req, unsigned int issue_flags)
219202
{
203+
struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
220204
int ret;
221205

222206
WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
223207

224-
ret = __io_setxattr(req, issue_flags, &req->file->f_path);
208+
ret = file_setxattr(req->file, &ix->ctx);
225209
io_xattr_finish(req, ret);
226210
return IOU_OK;
227211
}
228212

229213
int io_setxattr(struct io_kiocb *req, unsigned int issue_flags)
230214
{
231215
struct io_xattr *ix = io_kiocb_to_cmd(req, struct io_xattr);
232-
unsigned int lookup_flags = LOOKUP_FOLLOW;
233-
struct path path;
234216
int ret;
235217

236218
WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
237219

238-
retry:
239-
ret = filename_lookup(AT_FDCWD, ix->filename, lookup_flags, &path, NULL);
240-
if (!ret) {
241-
ret = __io_setxattr(req, issue_flags, &path);
242-
path_put(&path);
243-
if (retry_estale(ret, lookup_flags)) {
244-
lookup_flags |= LOOKUP_REVAL;
245-
goto retry;
246-
}
247-
}
248-
220+
ret = filename_setxattr(AT_FDCWD, ix->filename, LOOKUP_FOLLOW, &ix->ctx);
221+
ix->filename = NULL;
249222
io_xattr_finish(req, ret);
250223
return IOU_OK;
251224
}

0 commit comments

Comments
 (0)