Skip to content

Commit 7110f24

Browse files
committed
Merge tag 'vfs-6.13-rc7.fixes.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs fixes from Christian Brauner: "afs: - Fix the maximum cell name length - Fix merge preference rule failure condition fuse: - Fix fuse_get_user_pages() so it doesn't risk misleading the caller to think pages have been allocated when they actually haven't - Fix direct-io folio offset and length calculation netfs: - Fix async direct-io handling - Fix read-retry for filesystems that don't provide a ->prepare_read() method vfs: - Prevent truncating 64-bit offsets to 32-bits in iomap - Fix memory barrier interactions when polling - Remove MNT_ONRB to fix concurrent modification of @mnt->mnt_flags leading to MNT_ONRB to not be raised and invalid access to a list member" * tag 'vfs-6.13-rc7.fixes.2' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: poll: kill poll_does_not_wait() sock_poll_wait: kill the no longer necessary barrier after poll_wait() io_uring_poll: kill the no longer necessary barrier after poll_wait() poll_wait: kill the obsolete wait_address check poll_wait: add mb() to fix theoretical race between waitqueue_active() and .poll() afs: Fix merge preference rule failure condition netfs: Fix read-retry for fs with no ->prepare_read() netfs: Fix kernel async DIO fs: kill MNT_ONRB iomap: avoid avoid truncating 64-bit offset to 32 bits afs: Fix the maximum cell name length fuse: Set *nbytesp=0 in fuse_get_user_pages on allocation failure fuse: fix direct io folio offset and length calculation
2 parents 36eb219 + 1623bc2 commit 7110f24

File tree

15 files changed

+80
-66
lines changed

15 files changed

+80
-66
lines changed

fs/afs/addr_prefs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,10 @@ int afs_proc_addr_prefs_write(struct file *file, char *buf, size_t size)
413413

414414
do {
415415
argc = afs_split_string(&buf, argv, ARRAY_SIZE(argv));
416-
if (argc < 0)
417-
return argc;
416+
if (argc < 0) {
417+
ret = argc;
418+
goto done;
419+
}
418420
if (argc < 2)
419421
goto inval;
420422

fs/afs/afs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include <linux/in.h>
1212

13-
#define AFS_MAXCELLNAME 256 /* Maximum length of a cell name */
13+
#define AFS_MAXCELLNAME 253 /* Maximum length of a cell name (DNS limited) */
1414
#define AFS_MAXVOLNAME 64 /* Maximum length of a volume name */
1515
#define AFS_MAXNSERVERS 8 /* Maximum servers in a basic volume record */
1616
#define AFS_NMAXNSERVERS 13 /* Maximum servers in a N/U-class volume record */

fs/afs/afs_vl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#define AFS_VL_PORT 7003 /* volume location service port */
1414
#define VL_SERVICE 52 /* RxRPC service ID for the Volume Location service */
1515
#define YFS_VL_SERVICE 2503 /* Service ID for AuriStor upgraded VL service */
16+
#define YFS_VL_MAXCELLNAME 256 /* Maximum length of a cell name in YFS protocol */
1617

1718
enum AFSVL_Operations {
1819
VLGETENTRYBYID = 503, /* AFS Get VLDB entry by ID */

fs/afs/vl_alias.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,7 @@ static char *afs_vl_get_cell_name(struct afs_cell *cell, struct key *key)
253253
static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key)
254254
{
255255
struct afs_cell *master;
256+
size_t name_len;
256257
char *cell_name;
257258

258259
cell_name = afs_vl_get_cell_name(cell, key);
@@ -264,8 +265,11 @@ static int yfs_check_canonical_cell_name(struct afs_cell *cell, struct key *key)
264265
return 0;
265266
}
266267

267-
master = afs_lookup_cell(cell->net, cell_name, strlen(cell_name),
268-
NULL, false);
268+
name_len = strlen(cell_name);
269+
if (!name_len || name_len > AFS_MAXCELLNAME)
270+
master = ERR_PTR(-EOPNOTSUPP);
271+
else
272+
master = afs_lookup_cell(cell->net, cell_name, name_len, NULL, false);
269273
kfree(cell_name);
270274
if (IS_ERR(master))
271275
return PTR_ERR(master);

fs/afs/vlclient.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
697697
return ret;
698698

699699
namesz = ntohl(call->tmp);
700-
if (namesz > AFS_MAXCELLNAME)
700+
if (namesz > YFS_VL_MAXCELLNAME)
701701
return afs_protocol_error(call, afs_eproto_cellname_len);
702702
paddedsz = (namesz + 3) & ~3;
703703
call->count = namesz;

fs/fuse/file.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,8 +1541,10 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
15411541
*/
15421542
struct page **pages = kzalloc(max_pages * sizeof(struct page *),
15431543
GFP_KERNEL);
1544-
if (!pages)
1545-
return -ENOMEM;
1544+
if (!pages) {
1545+
ret = -ENOMEM;
1546+
goto out;
1547+
}
15461548

15471549
while (nbytes < *nbytesp && nr_pages < max_pages) {
15481550
unsigned nfolios, i;
@@ -1557,18 +1559,22 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
15571559

15581560
nbytes += ret;
15591561

1560-
ret += start;
1561-
/* Currently, all folios in FUSE are one page */
1562-
nfolios = DIV_ROUND_UP(ret, PAGE_SIZE);
1562+
nfolios = DIV_ROUND_UP(ret + start, PAGE_SIZE);
1563+
1564+
for (i = 0; i < nfolios; i++) {
1565+
struct folio *folio = page_folio(pages[i]);
1566+
unsigned int offset = start +
1567+
(folio_page_idx(folio, pages[i]) << PAGE_SHIFT);
1568+
unsigned int len = min_t(unsigned int, ret, PAGE_SIZE - start);
15631569

1564-
ap->descs[ap->num_folios].offset = start;
1565-
fuse_folio_descs_length_init(ap->descs, ap->num_folios, nfolios);
1566-
for (i = 0; i < nfolios; i++)
1567-
ap->folios[i + ap->num_folios] = page_folio(pages[i]);
1570+
ap->descs[ap->num_folios].offset = offset;
1571+
ap->descs[ap->num_folios].length = len;
1572+
ap->folios[ap->num_folios] = folio;
1573+
start = 0;
1574+
ret -= len;
1575+
ap->num_folios++;
1576+
}
15681577

1569-
ap->num_folios += nfolios;
1570-
ap->descs[ap->num_folios - 1].length -=
1571-
(PAGE_SIZE - ret) & (PAGE_SIZE - 1);
15721578
nr_pages += nfolios;
15731579
}
15741580
kfree(pages);
@@ -1584,6 +1590,7 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
15841590
else
15851591
ap->args.out_pages = true;
15861592

1593+
out:
15871594
*nbytesp = nbytes;
15881595

15891596
return ret < 0 ? ret : 0;

fs/iomap/buffered-io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,7 @@ static void iomap_write_delalloc_scan(struct inode *inode,
11381138
start_byte, end_byte, iomap, punch);
11391139

11401140
/* move offset to start of next folio in range */
1141-
start_byte = folio_next_index(folio) << PAGE_SHIFT;
1141+
start_byte = folio_pos(folio) + folio_size(folio);
11421142
folio_unlock(folio);
11431143
folio_put(folio);
11441144
}

fs/mount.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct mount {
3838
struct dentry *mnt_mountpoint;
3939
struct vfsmount mnt;
4040
union {
41+
struct rb_node mnt_node; /* node in the ns->mounts rbtree */
4142
struct rcu_head mnt_rcu;
4243
struct llist_node mnt_llist;
4344
};
@@ -51,10 +52,7 @@ struct mount {
5152
struct list_head mnt_child; /* and going through their mnt_child */
5253
struct list_head mnt_instance; /* mount instance on sb->s_mounts */
5354
const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
54-
union {
55-
struct rb_node mnt_node; /* Under ns->mounts */
56-
struct list_head mnt_list;
57-
};
55+
struct list_head mnt_list;
5856
struct list_head mnt_expire; /* link in fs-specific expiry list */
5957
struct list_head mnt_share; /* circular list of shared mounts */
6058
struct list_head mnt_slave_list;/* list of slave mounts */
@@ -145,11 +143,16 @@ static inline bool is_anon_ns(struct mnt_namespace *ns)
145143
return ns->seq == 0;
146144
}
147145

146+
static inline bool mnt_ns_attached(const struct mount *mnt)
147+
{
148+
return !RB_EMPTY_NODE(&mnt->mnt_node);
149+
}
150+
148151
static inline void move_from_ns(struct mount *mnt, struct list_head *dt_list)
149152
{
150-
WARN_ON(!(mnt->mnt.mnt_flags & MNT_ONRB));
151-
mnt->mnt.mnt_flags &= ~MNT_ONRB;
153+
WARN_ON(!mnt_ns_attached(mnt));
152154
rb_erase(&mnt->mnt_node, &mnt->mnt_ns->mounts);
155+
RB_CLEAR_NODE(&mnt->mnt_node);
153156
list_add_tail(&mnt->mnt_list, dt_list);
154157
}
155158

fs/namespace.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ static struct mount *alloc_vfsmnt(const char *name)
344344
INIT_HLIST_NODE(&mnt->mnt_mp_list);
345345
INIT_LIST_HEAD(&mnt->mnt_umounting);
346346
INIT_HLIST_HEAD(&mnt->mnt_stuck_children);
347+
RB_CLEAR_NODE(&mnt->mnt_node);
347348
mnt->mnt.mnt_idmap = &nop_mnt_idmap;
348349
}
349350
return mnt;
@@ -1124,7 +1125,7 @@ static void mnt_add_to_ns(struct mnt_namespace *ns, struct mount *mnt)
11241125
struct rb_node **link = &ns->mounts.rb_node;
11251126
struct rb_node *parent = NULL;
11261127

1127-
WARN_ON(mnt->mnt.mnt_flags & MNT_ONRB);
1128+
WARN_ON(mnt_ns_attached(mnt));
11281129
mnt->mnt_ns = ns;
11291130
while (*link) {
11301131
parent = *link;
@@ -1135,7 +1136,6 @@ static void mnt_add_to_ns(struct mnt_namespace *ns, struct mount *mnt)
11351136
}
11361137
rb_link_node(&mnt->mnt_node, parent, link);
11371138
rb_insert_color(&mnt->mnt_node, &ns->mounts);
1138-
mnt->mnt.mnt_flags |= MNT_ONRB;
11391139
}
11401140

11411141
/*
@@ -1305,7 +1305,7 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
13051305
}
13061306

13071307
mnt->mnt.mnt_flags = old->mnt.mnt_flags;
1308-
mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL|MNT_ONRB);
1308+
mnt->mnt.mnt_flags &= ~(MNT_WRITE_HOLD|MNT_MARKED|MNT_INTERNAL);
13091309

13101310
atomic_inc(&sb->s_active);
13111311
mnt->mnt.mnt_idmap = mnt_idmap_get(mnt_idmap(&old->mnt));
@@ -1763,7 +1763,7 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
17631763
/* Gather the mounts to umount */
17641764
for (p = mnt; p; p = next_mnt(p, mnt)) {
17651765
p->mnt.mnt_flags |= MNT_UMOUNT;
1766-
if (p->mnt.mnt_flags & MNT_ONRB)
1766+
if (mnt_ns_attached(p))
17671767
move_from_ns(p, &tmp_list);
17681768
else
17691769
list_move(&p->mnt_list, &tmp_list);
@@ -1912,16 +1912,14 @@ static int do_umount(struct mount *mnt, int flags)
19121912

19131913
event++;
19141914
if (flags & MNT_DETACH) {
1915-
if (mnt->mnt.mnt_flags & MNT_ONRB ||
1916-
!list_empty(&mnt->mnt_list))
1915+
if (mnt_ns_attached(mnt) || !list_empty(&mnt->mnt_list))
19171916
umount_tree(mnt, UMOUNT_PROPAGATE);
19181917
retval = 0;
19191918
} else {
19201919
shrink_submounts(mnt);
19211920
retval = -EBUSY;
19221921
if (!propagate_mount_busy(mnt, 2)) {
1923-
if (mnt->mnt.mnt_flags & MNT_ONRB ||
1924-
!list_empty(&mnt->mnt_list))
1922+
if (mnt_ns_attached(mnt) || !list_empty(&mnt->mnt_list))
19251923
umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);
19261924
retval = 0;
19271925
}

fs/netfs/direct_write.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *
6767
* allocate a sufficiently large bvec array and may shorten the
6868
* request.
6969
*/
70-
if (async || user_backed_iter(iter)) {
70+
if (user_backed_iter(iter)) {
7171
n = netfs_extract_user_iter(iter, len, &wreq->iter, 0);
7272
if (n < 0) {
7373
ret = n;
@@ -77,6 +77,11 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *
7777
wreq->direct_bv_count = n;
7878
wreq->direct_bv_unpin = iov_iter_extract_will_pin(iter);
7979
} else {
80+
/* If this is a kernel-generated async DIO request,
81+
* assume that any resources the iterator points to
82+
* (eg. a bio_vec array) will persist till the end of
83+
* the op.
84+
*/
8085
wreq->iter = *iter;
8186
}
8287

0 commit comments

Comments
 (0)