Skip to content

Commit 6f6efce

Browse files
committed
Merge tag 'xfs-6.9-merge-9' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs fixes from Chandan Babu: - Fix invalid pointer dereference by initializing xmbuf before tracepoint function is invoked - Use memalloc_nofs_save() when inserting into quota radix tree * tag 'xfs-6.9-merge-9' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: quota radix tree allocations need to be NOFS on insert xfs: fix dev_t usage in xmbuf tracepoints
2 parents c150b80 + 0c6ca06 commit 6f6efce

File tree

3 files changed

+22
-9
lines changed

3 files changed

+22
-9
lines changed

fs/xfs/xfs_buf_mem.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ xmbuf_alloc(
8181
/* ensure all writes are below EOF to avoid pagecache zeroing */
8282
i_size_write(inode, inode->i_sb->s_maxbytes);
8383

84-
trace_xmbuf_create(btp);
85-
8684
error = xfs_buf_cache_init(btp->bt_cache);
8785
if (error)
8886
goto out_file;
@@ -99,6 +97,8 @@ xmbuf_alloc(
9997
if (error)
10098
goto out_bcache;
10199

100+
trace_xmbuf_create(btp);
101+
102102
*btpp = btp;
103103
return 0;
104104

fs/xfs/xfs_dquot.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,12 @@ xfs_qm_dqget_cache_lookup(
811811
* caller should throw away the dquot and start over. Otherwise, the dquot
812812
* is returned locked (and held by the cache) as if there had been a cache
813813
* hit.
814+
*
815+
* The insert needs to be done under memalloc_nofs context because the radix
816+
* tree can do memory allocation during insert. The qi->qi_tree_lock is taken in
817+
* memory reclaim when freeing unused dquots, so we cannot have the radix tree
818+
* node allocation recursing into filesystem reclaim whilst we hold the
819+
* qi_tree_lock.
814820
*/
815821
static int
816822
xfs_qm_dqget_cache_insert(
@@ -820,25 +826,27 @@ xfs_qm_dqget_cache_insert(
820826
xfs_dqid_t id,
821827
struct xfs_dquot *dqp)
822828
{
829+
unsigned int nofs_flags;
823830
int error;
824831

832+
nofs_flags = memalloc_nofs_save();
825833
mutex_lock(&qi->qi_tree_lock);
826834
error = radix_tree_insert(tree, id, dqp);
827835
if (unlikely(error)) {
828836
/* Duplicate found! Caller must try again. */
829-
mutex_unlock(&qi->qi_tree_lock);
830837
trace_xfs_dqget_dup(dqp);
831-
return error;
838+
goto out_unlock;
832839
}
833840

834841
/* Return a locked dquot to the caller, with a reference taken. */
835842
xfs_dqlock(dqp);
836843
dqp->q_nrefs = 1;
837-
838844
qi->qi_dquots++;
839-
mutex_unlock(&qi->qi_tree_lock);
840845

841-
return 0;
846+
out_unlock:
847+
mutex_unlock(&qi->qi_tree_lock);
848+
memalloc_nofs_restore(nofs_flags);
849+
return error;
842850
}
843851

844852
/* Check our input parameters. */

fs/xfs/xfs_trace.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4626,14 +4626,16 @@ TRACE_EVENT(xmbuf_create,
46264626
char *path;
46274627
struct file *file = btp->bt_file;
46284628

4629+
__entry->dev = btp->bt_mount->m_super->s_dev;
46294630
__entry->ino = file_inode(file)->i_ino;
46304631
memset(pathname, 0, sizeof(pathname));
46314632
path = file_path(file, pathname, sizeof(pathname) - 1);
46324633
if (IS_ERR(path))
46334634
path = "(unknown)";
46344635
strncpy(__entry->pathname, path, sizeof(__entry->pathname));
46354636
),
4636-
TP_printk("xmino 0x%lx path '%s'",
4637+
TP_printk("dev %d:%d xmino 0x%lx path '%s'",
4638+
MAJOR(__entry->dev), MINOR(__entry->dev),
46374639
__entry->ino,
46384640
__entry->pathname)
46394641
);
@@ -4642,6 +4644,7 @@ TRACE_EVENT(xmbuf_free,
46424644
TP_PROTO(struct xfs_buftarg *btp),
46434645
TP_ARGS(btp),
46444646
TP_STRUCT__entry(
4647+
__field(dev_t, dev)
46454648
__field(unsigned long, ino)
46464649
__field(unsigned long long, bytes)
46474650
__field(loff_t, size)
@@ -4650,11 +4653,13 @@ TRACE_EVENT(xmbuf_free,
46504653
struct file *file = btp->bt_file;
46514654
struct inode *inode = file_inode(file);
46524655

4656+
__entry->dev = btp->bt_mount->m_super->s_dev;
46534657
__entry->size = i_size_read(inode);
46544658
__entry->bytes = (inode->i_blocks << SECTOR_SHIFT) + inode->i_bytes;
46554659
__entry->ino = inode->i_ino;
46564660
),
4657-
TP_printk("xmino 0x%lx mem_bytes 0x%llx isize 0x%llx",
4661+
TP_printk("dev %d:%d xmino 0x%lx mem_bytes 0x%llx isize 0x%llx",
4662+
MAJOR(__entry->dev), MINOR(__entry->dev),
46584663
__entry->ino,
46594664
__entry->bytes,
46604665
__entry->size)

0 commit comments

Comments
 (0)