Skip to content

Commit 1a0507d

Browse files
committed
Merge tag 'gfs2-v6.6-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - Don't update inode timestamps for direct writes (performance regression fix) - Skip no-op quota records instead of panicing - Fix a RCU race in gfs2_permission() - Various other smaller fixes and cleanups all over the place * tag 'gfs2-v6.6-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: (24 commits) gfs2: don't withdraw if init_threads() got interrupted gfs2: remove dead code in add_to_queue gfs2: Fix slab-use-after-free in gfs2_qd_dealloc gfs2: Silence "suspicious RCU usage in gfs2_permission" warning gfs2: fs: derive f_fsid from s_uuid gfs2: No longer use 'extern' in function declarations gfs2: Rename gfs2_lookup_{ simple => meta } gfs2: Convert gfs2_internal_read to folios gfs2: Convert stuffed_readpage to folios gfs2: Minor gfs2_write_jdata_batch PAGE_SIZE cleanup gfs2: Get rid of gfs2_alloc_blocks generation parameter gfs2: Add metapath_dibh helper gfs2: Clean up quota.c:print_message gfs2: Clean up gfs2_alloc_parms initializers gfs2: Two quota=account mode fixes gfs2: Stop using GFS2_BASIC_BLOCK and GFS2_BASIC_BLOCK_SHIFT gfs2: setattr_chown: Add missing initialization gfs2: fix an oops in gfs2_permission gfs2: ignore negated quota changes gfs2: Don't update inode timestamps for direct writes ...
2 parents 7f85193 + 0cdc6f4 commit 1a0507d

30 files changed

+421
-433
lines changed

fs/gfs2/acl.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
#define GFS2_ACL_MAX_ENTRIES(sdp) ((300 << (sdp)->sd_sb.sb_bsize_shift) >> 12)
1313

14-
extern struct posix_acl *gfs2_get_acl(struct inode *inode, int type, bool rcu);
15-
extern int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
16-
extern int gfs2_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
17-
struct posix_acl *acl, int type);
14+
struct posix_acl *gfs2_get_acl(struct inode *inode, int type, bool rcu);
15+
int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type);
16+
int gfs2_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
17+
struct posix_acl *acl, int type);
1818

1919
#endif /* __ACL_DOT_H__ */

fs/gfs2/aops.c

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ static int gfs2_jdata_writepage(struct page *page, struct writeback_control *wbc
155155
struct gfs2_inode *ip = GFS2_I(inode);
156156
struct gfs2_sbd *sdp = GFS2_SB(inode);
157157

158-
if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl)))
158+
if (gfs2_assert_withdraw(sdp, ip->i_gl->gl_state == LM_ST_EXCLUSIVE))
159159
goto out;
160160
if (folio_test_checked(folio) || current->journal_info)
161161
goto out_ignore;
@@ -214,12 +214,12 @@ static int gfs2_write_jdata_batch(struct address_space *mapping,
214214
unsigned nrblocks;
215215
int i;
216216
int ret;
217-
int nr_pages = 0;
217+
size_t size = 0;
218218
int nr_folios = folio_batch_count(fbatch);
219219

220220
for (i = 0; i < nr_folios; i++)
221-
nr_pages += folio_nr_pages(fbatch->folios[i]);
222-
nrblocks = nr_pages * (PAGE_SIZE >> inode->i_blkbits);
221+
size += folio_size(fbatch->folios[i]);
222+
nrblocks = size >> inode->i_blkbits;
223223

224224
ret = gfs2_trans_begin(sdp, nrblocks, nrblocks);
225225
if (ret < 0)
@@ -403,41 +403,39 @@ static int gfs2_jdata_writepages(struct address_space *mapping,
403403
}
404404

405405
/**
406-
* stuffed_readpage - Fill in a Linux page with stuffed file data
406+
* stuffed_readpage - Fill in a Linux folio with stuffed file data
407407
* @ip: the inode
408-
* @page: the page
408+
* @folio: the folio
409409
*
410410
* Returns: errno
411411
*/
412-
static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
412+
static int stuffed_readpage(struct gfs2_inode *ip, struct folio *folio)
413413
{
414414
struct buffer_head *dibh;
415-
u64 dsize = i_size_read(&ip->i_inode);
416-
void *kaddr;
415+
size_t i_size = i_size_read(&ip->i_inode);
416+
void *data;
417417
int error;
418418

419419
/*
420420
* Due to the order of unstuffing files and ->fault(), we can be
421-
* asked for a zero page in the case of a stuffed file being extended,
421+
* asked for a zero folio in the case of a stuffed file being extended,
422422
* so we need to supply one here. It doesn't happen often.
423423
*/
424-
if (unlikely(page->index)) {
425-
zero_user(page, 0, PAGE_SIZE);
426-
SetPageUptodate(page);
424+
if (unlikely(folio->index)) {
425+
folio_zero_range(folio, 0, folio_size(folio));
426+
folio_mark_uptodate(folio);
427427
return 0;
428428
}
429429

430430
error = gfs2_meta_inode_buffer(ip, &dibh);
431431
if (error)
432432
return error;
433433

434-
kaddr = kmap_local_page(page);
435-
memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), dsize);
436-
memset(kaddr + dsize, 0, PAGE_SIZE - dsize);
437-
kunmap_local(kaddr);
438-
flush_dcache_page(page);
434+
data = dibh->b_data + sizeof(struct gfs2_dinode);
435+
memcpy_to_folio(folio, 0, data, i_size);
436+
folio_zero_range(folio, i_size, folio_size(folio) - i_size);
439437
brelse(dibh);
440-
SetPageUptodate(page);
438+
folio_mark_uptodate(folio);
441439

442440
return 0;
443441
}
@@ -458,7 +456,7 @@ static int gfs2_read_folio(struct file *file, struct folio *folio)
458456
(i_blocksize(inode) == PAGE_SIZE && !folio_buffers(folio))) {
459457
error = iomap_read_folio(folio, &gfs2_iomap_ops);
460458
} else if (gfs2_is_stuffed(ip)) {
461-
error = stuffed_readpage(ip, &folio->page);
459+
error = stuffed_readpage(ip, folio);
462460
folio_unlock(folio);
463461
} else {
464462
error = mpage_read_folio(folio, gfs2_block_map);
@@ -479,31 +477,29 @@ static int gfs2_read_folio(struct file *file, struct folio *folio)
479477
*
480478
*/
481479

482-
int gfs2_internal_read(struct gfs2_inode *ip, char *buf, loff_t *pos,
483-
unsigned size)
480+
ssize_t gfs2_internal_read(struct gfs2_inode *ip, char *buf, loff_t *pos,
481+
size_t size)
484482
{
485483
struct address_space *mapping = ip->i_inode.i_mapping;
486484
unsigned long index = *pos >> PAGE_SHIFT;
487-
unsigned offset = *pos & (PAGE_SIZE - 1);
488-
unsigned copied = 0;
489-
unsigned amt;
490-
struct page *page;
485+
size_t copied = 0;
491486

492487
do {
493-
page = read_cache_page(mapping, index, gfs2_read_folio, NULL);
494-
if (IS_ERR(page)) {
495-
if (PTR_ERR(page) == -EINTR)
488+
size_t offset, chunk;
489+
struct folio *folio;
490+
491+
folio = read_cache_folio(mapping, index, gfs2_read_folio, NULL);
492+
if (IS_ERR(folio)) {
493+
if (PTR_ERR(folio) == -EINTR)
496494
continue;
497-
return PTR_ERR(page);
495+
return PTR_ERR(folio);
498496
}
499-
amt = size - copied;
500-
if (offset + size > PAGE_SIZE)
501-
amt = PAGE_SIZE - offset;
502-
memcpy_from_page(buf + copied, page, offset, amt);
503-
put_page(page);
504-
copied += amt;
505-
index++;
506-
offset = 0;
497+
offset = *pos + copied - folio_pos(folio);
498+
chunk = min(size - copied, folio_size(folio) - offset);
499+
memcpy_from_folio(buf + copied, folio, offset, chunk);
500+
index = folio_next_index(folio);
501+
folio_put(folio);
502+
copied += chunk;
507503
} while(copied < size);
508504
(*pos) += size;
509505
return size;

fs/gfs2/aops.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
#include "incore.h"
1010

11-
extern void adjust_fs_space(struct inode *inode);
12-
extern void gfs2_trans_add_databufs(struct gfs2_inode *ip, struct folio *folio,
13-
size_t from, size_t len);
11+
void adjust_fs_space(struct inode *inode);
12+
void gfs2_trans_add_databufs(struct gfs2_inode *ip, struct folio *folio,
13+
size_t from, size_t len);
1414

1515
#endif /* __AOPS_DOT_H__ */

fs/gfs2/bmap.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static int __gfs2_unstuff_inode(struct gfs2_inode *ip, struct folio *folio)
104104
and write it out to disk */
105105

106106
unsigned int n = 1;
107-
error = gfs2_alloc_blocks(ip, &block, &n, 0, NULL);
107+
error = gfs2_alloc_blocks(ip, &block, &n, 0);
108108
if (error)
109109
goto out_brelse;
110110
if (isdir) {
@@ -315,6 +315,12 @@ static void gfs2_metapath_ra(struct gfs2_glock *gl, __be64 *start, __be64 *end)
315315
}
316316
}
317317

318+
static inline struct buffer_head *
319+
metapath_dibh(struct metapath *mp)
320+
{
321+
return mp->mp_bh[0];
322+
}
323+
318324
static int __fillup_metapath(struct gfs2_inode *ip, struct metapath *mp,
319325
unsigned int x, unsigned int h)
320326
{
@@ -413,13 +419,12 @@ static void release_metapath(struct metapath *mp)
413419
* gfs2_extent_length - Returns length of an extent of blocks
414420
* @bh: The metadata block
415421
* @ptr: Current position in @bh
416-
* @limit: Max extent length to return
417422
* @eob: Set to 1 if we hit "end of block"
418423
*
419424
* Returns: The length of the extent (minimum of one block)
420425
*/
421426

422-
static inline unsigned int gfs2_extent_length(struct buffer_head *bh, __be64 *ptr, size_t limit, int *eob)
427+
static inline unsigned int gfs2_extent_length(struct buffer_head *bh, __be64 *ptr, int *eob)
423428
{
424429
const __be64 *end = (__be64 *)(bh->b_data + bh->b_size);
425430
const __be64 *first = ptr;
@@ -658,7 +663,7 @@ static int __gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
658663
{
659664
struct gfs2_inode *ip = GFS2_I(inode);
660665
struct gfs2_sbd *sdp = GFS2_SB(inode);
661-
struct buffer_head *dibh = mp->mp_bh[0];
666+
struct buffer_head *dibh = metapath_dibh(mp);
662667
u64 bn;
663668
unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
664669
size_t dblks = iomap->length >> inode->i_blkbits;
@@ -700,7 +705,7 @@ static int __gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
700705
i = mp->mp_aheight;
701706
do {
702707
n = blks - alloced;
703-
ret = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL);
708+
ret = gfs2_alloc_blocks(ip, &bn, &n, 0);
704709
if (ret)
705710
goto out;
706711
alloced += n;
@@ -911,7 +916,7 @@ static int __gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
911916
goto do_alloc;
912917

913918
bh = mp->mp_bh[ip->i_height - 1];
914-
len = gfs2_extent_length(bh, ptr, len, &eob);
919+
len = gfs2_extent_length(bh, ptr, &eob);
915920

916921
iomap->addr = be64_to_cpu(*ptr) << inode->i_blkbits;
917922
iomap->length = len << inode->i_blkbits;

fs/gfs2/bmap.h

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,24 @@ static inline void gfs2_write_calc_reserv(const struct gfs2_inode *ip,
4646
extern const struct iomap_ops gfs2_iomap_ops;
4747
extern const struct iomap_writeback_ops gfs2_writeback_ops;
4848

49-
extern int gfs2_unstuff_dinode(struct gfs2_inode *ip);
50-
extern int gfs2_block_map(struct inode *inode, sector_t lblock,
51-
struct buffer_head *bh, int create);
52-
extern int gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
53-
struct iomap *iomap);
54-
extern int gfs2_iomap_alloc(struct inode *inode, loff_t pos, loff_t length,
55-
struct iomap *iomap);
56-
extern int gfs2_get_extent(struct inode *inode, u64 lblock, u64 *dblock,
57-
unsigned int *extlen);
58-
extern int gfs2_alloc_extent(struct inode *inode, u64 lblock, u64 *dblock,
59-
unsigned *extlen, bool *new);
60-
extern int gfs2_setattr_size(struct inode *inode, u64 size);
61-
extern int gfs2_truncatei_resume(struct gfs2_inode *ip);
62-
extern int gfs2_file_dealloc(struct gfs2_inode *ip);
63-
extern int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
64-
unsigned int len);
65-
extern int gfs2_map_journal_extents(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd);
66-
extern void gfs2_free_journal_extents(struct gfs2_jdesc *jd);
67-
extern int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length);
49+
int gfs2_unstuff_dinode(struct gfs2_inode *ip);
50+
int gfs2_block_map(struct inode *inode, sector_t lblock,
51+
struct buffer_head *bh, int create);
52+
int gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length,
53+
struct iomap *iomap);
54+
int gfs2_iomap_alloc(struct inode *inode, loff_t pos, loff_t length,
55+
struct iomap *iomap);
56+
int gfs2_get_extent(struct inode *inode, u64 lblock, u64 *dblock,
57+
unsigned int *extlen);
58+
int gfs2_alloc_extent(struct inode *inode, u64 lblock, u64 *dblock,
59+
unsigned *extlen, bool *new);
60+
int gfs2_setattr_size(struct inode *inode, u64 size);
61+
int gfs2_truncatei_resume(struct gfs2_inode *ip);
62+
int gfs2_file_dealloc(struct gfs2_inode *ip);
63+
int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
64+
unsigned int len);
65+
int gfs2_map_journal_extents(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd);
66+
void gfs2_free_journal_extents(struct gfs2_jdesc *jd);
67+
int __gfs2_punch_hole(struct file *file, loff_t offset, loff_t length);
6868

6969
#endif /* __BMAP_DOT_H__ */

fs/gfs2/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ static struct gfs2_leaf *new_leaf(struct inode *inode, struct buffer_head **pbh,
868868
struct gfs2_dirent *dent;
869869
struct timespec64 tv = current_time(inode);
870870

871-
error = gfs2_alloc_blocks(ip, &bn, &n, 0, NULL);
871+
error = gfs2_alloc_blocks(ip, &bn, &n, 0);
872872
if (error)
873873
return NULL;
874874
bh = gfs2_meta_new(ip->i_gl, bn);

fs/gfs2/dir.h

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,32 @@ struct gfs2_diradd {
2323
int save_loc;
2424
};
2525

26-
extern struct inode *gfs2_dir_search(struct inode *dir,
27-
const struct qstr *filename,
28-
bool fail_on_exist);
29-
extern int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
30-
const struct gfs2_inode *ip);
31-
extern int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
32-
const struct gfs2_inode *ip, struct gfs2_diradd *da);
26+
struct inode *gfs2_dir_search(struct inode *dir,
27+
const struct qstr *filename,
28+
bool fail_on_exist);
29+
int gfs2_dir_check(struct inode *dir, const struct qstr *filename,
30+
const struct gfs2_inode *ip);
31+
int gfs2_dir_add(struct inode *inode, const struct qstr *filename,
32+
const struct gfs2_inode *ip, struct gfs2_diradd *da);
3333
static inline void gfs2_dir_no_add(struct gfs2_diradd *da)
3434
{
3535
brelse(da->bh);
3636
da->bh = NULL;
3737
}
38-
extern int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry);
39-
extern int gfs2_dir_read(struct inode *inode, struct dir_context *ctx,
40-
struct file_ra_state *f_ra);
41-
extern int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
42-
const struct gfs2_inode *nip, unsigned int new_type);
38+
int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry);
39+
int gfs2_dir_read(struct inode *inode, struct dir_context *ctx,
40+
struct file_ra_state *f_ra);
41+
int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
42+
const struct gfs2_inode *nip, unsigned int new_type);
4343

44-
extern int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);
44+
int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip);
4545

46-
extern int gfs2_diradd_alloc_required(struct inode *dir,
47-
const struct qstr *filename,
48-
struct gfs2_diradd *da);
49-
extern int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block,
50-
struct buffer_head **bhp);
51-
extern void gfs2_dir_hash_inval(struct gfs2_inode *ip);
46+
int gfs2_diradd_alloc_required(struct inode *dir,
47+
const struct qstr *filename,
48+
struct gfs2_diradd *da);
49+
int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block,
50+
struct buffer_head **bhp);
51+
void gfs2_dir_hash_inval(struct gfs2_inode *ip);
5252

5353
static inline u32 gfs2_disk_hash(const char *data, int len)
5454
{

fs/gfs2/file.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
418418
struct inode *inode = file_inode(vmf->vma->vm_file);
419419
struct gfs2_inode *ip = GFS2_I(inode);
420420
struct gfs2_sbd *sdp = GFS2_SB(inode);
421-
struct gfs2_alloc_parms ap = { .aflags = 0, };
421+
struct gfs2_alloc_parms ap = {};
422422
u64 offset = page_offset(page);
423423
unsigned int data_blocks, ind_blocks, rblocks;
424424
vm_fault_t ret = VM_FAULT_LOCKED;
@@ -1120,14 +1120,16 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
11201120
if (ret)
11211121
goto out_unlock;
11221122

1123-
ret = file_update_time(file);
1124-
if (ret)
1125-
goto out_unlock;
1126-
11271123
if (iocb->ki_flags & IOCB_DIRECT) {
11281124
struct address_space *mapping = file->f_mapping;
11291125
ssize_t buffered, ret2;
11301126

1127+
/*
1128+
* Note that under direct I/O, we don't allow and inode
1129+
* timestamp updates, so we're not calling file_update_time()
1130+
* here.
1131+
*/
1132+
11311133
ret = gfs2_file_direct_write(iocb, from, &gh);
11321134
if (ret < 0 || !iov_iter_count(from))
11331135
goto out_unlock;
@@ -1154,6 +1156,10 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
11541156
if (!ret || ret2 > 0)
11551157
ret += ret2;
11561158
} else {
1159+
ret = file_update_time(file);
1160+
if (ret)
1161+
goto out_unlock;
1162+
11571163
ret = gfs2_file_buffered_write(iocb, from, &gh);
11581164
if (likely(ret > 0))
11591165
ret = generic_write_sync(iocb, ret);
@@ -1245,7 +1251,7 @@ static long __gfs2_fallocate(struct file *file, int mode, loff_t offset, loff_t
12451251
struct inode *inode = file_inode(file);
12461252
struct gfs2_sbd *sdp = GFS2_SB(inode);
12471253
struct gfs2_inode *ip = GFS2_I(inode);
1248-
struct gfs2_alloc_parms ap = { .aflags = 0, };
1254+
struct gfs2_alloc_parms ap = {};
12491255
unsigned int data_blocks = 0, ind_blocks = 0, rblocks;
12501256
loff_t bytes, max_bytes, max_blks;
12511257
int error;

fs/gfs2/glock.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1524,7 +1524,6 @@ __acquires(&gl->gl_lockref.lock)
15241524
return;
15251525
}
15261526
list_add_tail(&gh->gh_list, insert_pt);
1527-
gh = list_first_entry(&gl->gl_holders, struct gfs2_holder, gh_list);
15281527
spin_unlock(&gl->gl_lockref.lock);
15291528
if (sdp->sd_lockstruct.ls_ops->lm_cancel)
15301529
sdp->sd_lockstruct.ls_ops->lm_cancel(gl);

0 commit comments

Comments
 (0)