Skip to content

Commit e7989f9

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse
Pull fuse updates from Miklos Szeredi: "This fixes a regression (spotted by the Sandstorm.io folks) in the pid namespace handling introduced in 4.12. There's also a fix for honoring sync/dsync flags for pwritev2()" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse: fuse: getattr cleanup fuse: honor iocb sync flags on write fuse: allow server to run in different pid_ns
2 parents c353f88 + 5b97eea commit e7989f9

File tree

5 files changed

+53
-54
lines changed

5 files changed

+53
-54
lines changed

fs/fuse/cuse.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ static struct list_head *cuse_conntbl_head(dev_t devt)
9090

9191
static ssize_t cuse_read_iter(struct kiocb *kiocb, struct iov_iter *to)
9292
{
93-
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb->ki_filp);
93+
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb);
9494
loff_t pos = 0;
9595

9696
return fuse_direct_io(&io, to, &pos, FUSE_DIO_CUSE);
9797
}
9898

9999
static ssize_t cuse_write_iter(struct kiocb *kiocb, struct iov_iter *from)
100100
{
101-
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb->ki_filp);
101+
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(kiocb);
102102
loff_t pos = 0;
103103
/*
104104
* No locking or generic_write_checks(), the server is

fs/fuse/dev.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,9 +1222,6 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
12221222
struct fuse_in *in;
12231223
unsigned reqsize;
12241224

1225-
if (task_active_pid_ns(current) != fc->pid_ns)
1226-
return -EIO;
1227-
12281225
restart:
12291226
spin_lock(&fiq->waitq.lock);
12301227
err = -EAGAIN;
@@ -1262,6 +1259,13 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
12621259

12631260
in = &req->in;
12641261
reqsize = in->h.len;
1262+
1263+
if (task_active_pid_ns(current) != fc->pid_ns) {
1264+
rcu_read_lock();
1265+
in->h.pid = pid_vnr(find_pid_ns(in->h.pid, fc->pid_ns));
1266+
rcu_read_unlock();
1267+
}
1268+
12651269
/* If request is too large, reply with an error and restart the read */
12661270
if (nbytes < reqsize) {
12671271
req->out.h.error = -EIO;
@@ -1823,9 +1827,6 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
18231827
struct fuse_req *req;
18241828
struct fuse_out_header oh;
18251829

1826-
if (task_active_pid_ns(current) != fc->pid_ns)
1827-
return -EIO;
1828-
18291830
if (nbytes < sizeof(struct fuse_out_header))
18301831
return -EINVAL;
18311832

fs/fuse/dir.c

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -923,33 +923,29 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
923923
return err;
924924
}
925925

926-
int fuse_update_attributes(struct inode *inode, struct kstat *stat,
927-
struct file *file, bool *refreshed)
926+
static int fuse_update_get_attr(struct inode *inode, struct file *file,
927+
struct kstat *stat)
928928
{
929929
struct fuse_inode *fi = get_fuse_inode(inode);
930-
int err;
931-
bool r;
930+
int err = 0;
932931

933932
if (time_before64(fi->i_time, get_jiffies_64())) {
934-
r = true;
935933
forget_all_cached_acls(inode);
936934
err = fuse_do_getattr(inode, stat, file);
937-
} else {
938-
r = false;
939-
err = 0;
940-
if (stat) {
941-
generic_fillattr(inode, stat);
942-
stat->mode = fi->orig_i_mode;
943-
stat->ino = fi->orig_ino;
944-
}
935+
} else if (stat) {
936+
generic_fillattr(inode, stat);
937+
stat->mode = fi->orig_i_mode;
938+
stat->ino = fi->orig_ino;
945939
}
946940

947-
if (refreshed != NULL)
948-
*refreshed = r;
949-
950941
return err;
951942
}
952943

944+
int fuse_update_attributes(struct inode *inode, struct file *file)
945+
{
946+
return fuse_update_get_attr(inode, file, NULL);
947+
}
948+
953949
int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
954950
u64 child_nodeid, struct qstr *name)
955951
{
@@ -1786,7 +1782,7 @@ static int fuse_getattr(const struct path *path, struct kstat *stat,
17861782
if (!fuse_allow_current_process(fc))
17871783
return -EACCES;
17881784

1789-
return fuse_update_attributes(inode, stat, NULL, NULL);
1785+
return fuse_update_get_attr(inode, NULL, stat);
17901786
}
17911787

17921788
static const struct inode_operations fuse_dir_inode_operations = {

fs/fuse/file.c

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ static size_t fuse_async_req_send(struct fuse_conn *fc, struct fuse_req *req,
645645
static size_t fuse_send_read(struct fuse_req *req, struct fuse_io_priv *io,
646646
loff_t pos, size_t count, fl_owner_t owner)
647647
{
648-
struct file *file = io->file;
648+
struct file *file = io->iocb->ki_filp;
649649
struct fuse_file *ff = file->private_data;
650650
struct fuse_conn *fc = ff->fc;
651651

@@ -707,7 +707,8 @@ static void fuse_short_read(struct fuse_req *req, struct inode *inode,
707707

708708
static int fuse_do_readpage(struct file *file, struct page *page)
709709
{
710-
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file);
710+
struct kiocb iocb;
711+
struct fuse_io_priv io;
711712
struct inode *inode = page->mapping->host;
712713
struct fuse_conn *fc = get_fuse_conn(inode);
713714
struct fuse_req *req;
@@ -735,6 +736,8 @@ static int fuse_do_readpage(struct file *file, struct page *page)
735736
req->num_pages = 1;
736737
req->pages[0] = page;
737738
req->page_descs[0].length = count;
739+
init_sync_kiocb(&iocb, file);
740+
io = (struct fuse_io_priv) FUSE_IO_PRIV_SYNC(&iocb);
738741
num_read = fuse_send_read(req, &io, pos, count, NULL);
739742
err = req->out.h.error;
740743

@@ -923,7 +926,7 @@ static ssize_t fuse_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
923926
if (fc->auto_inval_data ||
924927
(iocb->ki_pos + iov_iter_count(to) > i_size_read(inode))) {
925928
int err;
926-
err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
929+
err = fuse_update_attributes(inode, iocb->ki_filp);
927930
if (err)
928931
return err;
929932
}
@@ -957,13 +960,18 @@ static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
957960
static size_t fuse_send_write(struct fuse_req *req, struct fuse_io_priv *io,
958961
loff_t pos, size_t count, fl_owner_t owner)
959962
{
960-
struct file *file = io->file;
963+
struct kiocb *iocb = io->iocb;
964+
struct file *file = iocb->ki_filp;
961965
struct fuse_file *ff = file->private_data;
962966
struct fuse_conn *fc = ff->fc;
963967
struct fuse_write_in *inarg = &req->misc.write.in;
964968

965969
fuse_write_fill(req, ff, pos, count);
966970
inarg->flags = file->f_flags;
971+
if (iocb->ki_flags & IOCB_DSYNC)
972+
inarg->flags |= O_DSYNC;
973+
if (iocb->ki_flags & IOCB_SYNC)
974+
inarg->flags |= O_SYNC;
967975
if (owner != NULL) {
968976
inarg->write_flags |= FUSE_WRITE_LOCKOWNER;
969977
inarg->lock_owner = fuse_lock_owner_id(fc, owner);
@@ -993,14 +1001,14 @@ bool fuse_write_update_size(struct inode *inode, loff_t pos)
9931001
return ret;
9941002
}
9951003

996-
static size_t fuse_send_write_pages(struct fuse_req *req, struct file *file,
1004+
static size_t fuse_send_write_pages(struct fuse_req *req, struct kiocb *iocb,
9971005
struct inode *inode, loff_t pos,
9981006
size_t count)
9991007
{
10001008
size_t res;
10011009
unsigned offset;
10021010
unsigned i;
1003-
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file);
1011+
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb);
10041012

10051013
for (i = 0; i < req->num_pages; i++)
10061014
fuse_wait_on_page_writeback(inode, req->pages[i]->index);
@@ -1100,7 +1108,7 @@ static inline unsigned fuse_wr_pages(loff_t pos, size_t len)
11001108
FUSE_MAX_PAGES_PER_REQ);
11011109
}
11021110

1103-
static ssize_t fuse_perform_write(struct file *file,
1111+
static ssize_t fuse_perform_write(struct kiocb *iocb,
11041112
struct address_space *mapping,
11051113
struct iov_iter *ii, loff_t pos)
11061114
{
@@ -1133,7 +1141,7 @@ static ssize_t fuse_perform_write(struct file *file,
11331141
} else {
11341142
size_t num_written;
11351143

1136-
num_written = fuse_send_write_pages(req, file, inode,
1144+
num_written = fuse_send_write_pages(req, iocb, inode,
11371145
pos, count);
11381146
err = req->out.h.error;
11391147
if (!err) {
@@ -1169,7 +1177,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
11691177

11701178
if (get_fuse_conn(inode)->writeback_cache) {
11711179
/* Update size (EOF optimization) and mode (SUID clearing) */
1172-
err = fuse_update_attributes(mapping->host, NULL, file, NULL);
1180+
err = fuse_update_attributes(mapping->host, file);
11731181
if (err)
11741182
return err;
11751183

@@ -1201,7 +1209,7 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
12011209

12021210
pos += written;
12031211

1204-
written_buffered = fuse_perform_write(file, mapping, from, pos);
1212+
written_buffered = fuse_perform_write(iocb, mapping, from, pos);
12051213
if (written_buffered < 0) {
12061214
err = written_buffered;
12071215
goto out;
@@ -1220,13 +1228,15 @@ static ssize_t fuse_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
12201228
written += written_buffered;
12211229
iocb->ki_pos = pos + written_buffered;
12221230
} else {
1223-
written = fuse_perform_write(file, mapping, from, iocb->ki_pos);
1231+
written = fuse_perform_write(iocb, mapping, from, iocb->ki_pos);
12241232
if (written >= 0)
12251233
iocb->ki_pos += written;
12261234
}
12271235
out:
12281236
current->backing_dev_info = NULL;
12291237
inode_unlock(inode);
1238+
if (written > 0)
1239+
written = generic_write_sync(iocb, written);
12301240

12311241
return written ? written : err;
12321242
}
@@ -1317,7 +1327,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
13171327
{
13181328
int write = flags & FUSE_DIO_WRITE;
13191329
int cuse = flags & FUSE_DIO_CUSE;
1320-
struct file *file = io->file;
1330+
struct file *file = io->iocb->ki_filp;
13211331
struct inode *inode = file->f_mapping->host;
13221332
struct fuse_file *ff = file->private_data;
13231333
struct fuse_conn *fc = ff->fc;
@@ -1399,8 +1409,7 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io,
13991409
loff_t *ppos)
14001410
{
14011411
ssize_t res;
1402-
struct file *file = io->file;
1403-
struct inode *inode = file_inode(file);
1412+
struct inode *inode = file_inode(io->iocb->ki_filp);
14041413

14051414
if (is_bad_inode(inode))
14061415
return -EIO;
@@ -1414,15 +1423,14 @@ static ssize_t __fuse_direct_read(struct fuse_io_priv *io,
14141423

14151424
static ssize_t fuse_direct_read_iter(struct kiocb *iocb, struct iov_iter *to)
14161425
{
1417-
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb->ki_filp);
1426+
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb);
14181427
return __fuse_direct_read(&io, to, &iocb->ki_pos);
14191428
}
14201429

14211430
static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from)
14221431
{
1423-
struct file *file = iocb->ki_filp;
1424-
struct inode *inode = file_inode(file);
1425-
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(file);
1432+
struct inode *inode = file_inode(iocb->ki_filp);
1433+
struct fuse_io_priv io = FUSE_IO_PRIV_SYNC(iocb);
14261434
ssize_t res;
14271435

14281436
if (is_bad_inode(inode))
@@ -2181,9 +2189,6 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
21812189
if ((fl->fl_flags & FL_CLOSE_POSIX) == FL_CLOSE_POSIX)
21822190
return 0;
21832191

2184-
if (pid && pid_nr == 0)
2185-
return -EOVERFLOW;
2186-
21872192
fuse_lk_fill(&args, file, fl, opcode, pid_nr, flock, &inarg);
21882193
err = fuse_simple_request(fc, &args);
21892194

@@ -2303,7 +2308,7 @@ static loff_t fuse_lseek(struct file *file, loff_t offset, int whence)
23032308
return vfs_setpos(file, outarg.offset, inode->i_sb->s_maxbytes);
23042309

23052310
fallback:
2306-
err = fuse_update_attributes(inode, NULL, file, NULL);
2311+
err = fuse_update_attributes(inode, file);
23072312
if (!err)
23082313
return generic_file_llseek(file, offset, whence);
23092314
else
@@ -2323,7 +2328,7 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int whence)
23232328
break;
23242329
case SEEK_END:
23252330
inode_lock(inode);
2326-
retval = fuse_update_attributes(inode, NULL, file, NULL);
2331+
retval = fuse_update_attributes(inode, file);
23272332
if (!retval)
23282333
retval = generic_file_llseek(file, offset, whence);
23292334
inode_unlock(inode);
@@ -2874,7 +2879,6 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
28742879
io->offset = offset;
28752880
io->write = (iov_iter_rw(iter) == WRITE);
28762881
io->err = 0;
2877-
io->file = file;
28782882
/*
28792883
* By default, we want to optimize all I/Os with async request
28802884
* submission to the client filesystem if supported.

fs/fuse/fuse_i.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,16 +252,15 @@ struct fuse_io_priv {
252252
bool should_dirty;
253253
int err;
254254
struct kiocb *iocb;
255-
struct file *file;
256255
struct completion *done;
257256
bool blocking;
258257
};
259258

260-
#define FUSE_IO_PRIV_SYNC(f) \
259+
#define FUSE_IO_PRIV_SYNC(i) \
261260
{ \
262261
.refcnt = KREF_INIT(1), \
263262
.async = 0, \
264-
.file = f, \
263+
.iocb = i, \
265264
}
266265

267266
/**
@@ -905,8 +904,7 @@ u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id);
905904

906905
void fuse_update_ctime(struct inode *inode);
907906

908-
int fuse_update_attributes(struct inode *inode, struct kstat *stat,
909-
struct file *file, bool *refreshed);
907+
int fuse_update_attributes(struct inode *inode, struct file *file);
910908

911909
void fuse_flush_writepages(struct inode *inode);
912910

0 commit comments

Comments
 (0)