Updated from Linux LTS 3.10.25 to 3.10.26

This commit is contained in:
Nathan
2025-04-09 20:15:34 -05:00
parent 92cb237c3b
commit c205d496ee
118 changed files with 902 additions and 407 deletions

View File

@@ -213,9 +213,13 @@ static int readpage_nounlock(struct file *filp, struct page *page)
if (err < 0) {
SetPageError(page);
goto out;
} else if (err < PAGE_CACHE_SIZE) {
} else {
if (err < PAGE_CACHE_SIZE) {
/* zero fill remainder of page */
zero_user_segment(page, err, PAGE_CACHE_SIZE);
zero_user_segment(page, err, PAGE_CACHE_SIZE);
} else {
flush_dcache_page(page);
}
}
SetPageUptodate(page);

View File

@@ -313,9 +313,9 @@ static int striped_read(struct inode *inode,
{
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
struct ceph_inode_info *ci = ceph_inode(inode);
u64 pos, this_len;
u64 pos, this_len, left;
int io_align, page_align;
int left, pages_left;
int pages_left;
int read;
struct page **page_pos;
int ret;
@@ -346,47 +346,40 @@ more:
ret = 0;
hit_stripe = this_len < left;
was_short = ret >= 0 && ret < this_len;
dout("striped_read %llu~%u (read %u) got %d%s%s\n", pos, left, read,
dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read,
ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
if (ret > 0) {
int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
if (read < pos - off) {
dout(" zero gap %llu to %llu\n", off + read, pos);
ceph_zero_page_vector_range(page_align + read,
pos - off - read, pages);
if (ret >= 0) {
int didpages;
if (was_short && (pos + ret < inode->i_size)) {
u64 tmp = min(this_len - ret,
inode->i_size - pos - ret);
dout(" zero gap %llu to %llu\n",
pos + ret, pos + ret + tmp);
ceph_zero_page_vector_range(page_align + read + ret,
tmp, pages);
ret += tmp;
}
didpages = (page_align + ret) >> PAGE_CACHE_SHIFT;
pos += ret;
read = pos - off;
left -= ret;
page_pos += didpages;
pages_left -= didpages;
/* hit stripe? */
if (left && hit_stripe)
/* hit stripe and need continue*/
if (left && hit_stripe && pos < inode->i_size)
goto more;
}
if (was_short) {
if (read > 0) {
ret = read;
/* did we bounce off eof? */
if (pos + left > inode->i_size)
*checkeof = 1;
/* zero trailing bytes (inside i_size) */
if (left > 0 && pos < inode->i_size) {
if (pos + left > inode->i_size)
left = inode->i_size - pos;
dout("zero tail %d\n", left);
ceph_zero_page_vector_range(page_align + read, left,
pages);
read += left;
}
}
if (ret >= 0)
ret = read;
dout("striped_read returns %d\n", ret);
return ret;
}
@@ -618,6 +611,8 @@ out:
if (check_caps)
ceph_check_caps(ceph_inode(inode), CHECK_CAPS_AUTHONLY,
NULL);
} else if (ret != -EOLDSNAPC && written > 0) {
ret = written;
}
return ret;
}

View File

@@ -211,8 +211,12 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
snprintf(dl.object_name, sizeof(dl.object_name), "%llx.%08llx",
ceph_ino(inode), dl.object_no);
ceph_calc_ceph_pg(&pgid, dl.object_name, osdc->osdmap,
ceph_file_layout_pg_pool(ci->i_layout));
r = ceph_calc_ceph_pg(&pgid, dl.object_name, osdc->osdmap,
ceph_file_layout_pg_pool(ci->i_layout));
if (r < 0) {
up_read(&osdc->map_sem);
return r;
}
dl.osd = ceph_calc_pg_primary(osdc->osdmap, pgid);
if (dl.osd >= 0) {

View File

@@ -414,6 +414,9 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
{
struct ceph_mds_session *s;
if (mds >= mdsc->mdsmap->m_max_mds)
return ERR_PTR(-EINVAL);
s = kzalloc(sizeof(*s), GFP_NOFS);
if (!s)
return ERR_PTR(-ENOMEM);
@@ -639,6 +642,8 @@ static void __unregister_request(struct ceph_mds_client *mdsc,
req->r_unsafe_dir = NULL;
}
complete_all(&req->r_safe_completion);
ceph_mdsc_put_request(req);
}
@@ -1840,8 +1845,11 @@ static int __do_request(struct ceph_mds_client *mdsc,
int mds = -1;
int err = -EAGAIN;
if (req->r_err || req->r_got_result)
if (req->r_err || req->r_got_result) {
if (req->r_aborted)
__unregister_request(mdsc, req);
goto out;
}
if (req->r_timeout &&
time_after_eq(jiffies, req->r_started + req->r_timeout)) {
@@ -2151,7 +2159,6 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
if (head->safe) {
req->r_got_safe = true;
__unregister_request(mdsc, req);
complete_all(&req->r_safe_completion);
if (req->r_got_unsafe) {
/*
@@ -3040,8 +3047,10 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc)
fsc->mdsc = mdsc;
mutex_init(&mdsc->mutex);
mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS);
if (mdsc->mdsmap == NULL)
if (mdsc->mdsmap == NULL) {
kfree(mdsc);
return -ENOMEM;
}
init_completion(&mdsc->safe_umount_waiters);
init_waitqueue_head(&mdsc->session_close_wq);

View File

@@ -138,6 +138,8 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
m->m_info[mds].export_targets =
kcalloc(num_export_targets, sizeof(u32),
GFP_NOFS);
if (m->m_info[mds].export_targets == NULL)
goto badmem;
for (j = 0; j < num_export_targets; j++)
m->m_info[mds].export_targets[j] =
ceph_decode_32(&pexport_targets);
@@ -170,7 +172,7 @@ bad:
DUMP_PREFIX_OFFSET, 16, 1,
start, end - start, true);
ceph_mdsmap_destroy(m);
return ERR_PTR(-EINVAL);
return ERR_PTR(err);
}
void ceph_mdsmap_destroy(struct ceph_mdsmap *m)

View File

@@ -357,7 +357,7 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
}
err = -EINVAL;
dev_name_end--; /* back up to ':' separator */
if (*dev_name_end != ':') {
if (dev_name_end < dev_name || *dev_name_end != ':') {
pr_err("device name is missing path (no : separator in %s)\n",
dev_name);
goto out;

View File

@@ -999,6 +999,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
struct address_space *mapping = inode->i_mapping;
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder gh;
int rv;
@@ -1019,6 +1020,35 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
if (rv != 1)
goto out; /* dio not valid, fall back to buffered i/o */
/*
* Now since we are holding a deferred (CW) lock at this point, you
* might be wondering why this is ever needed. There is a case however
* where we've granted a deferred local lock against a cached exclusive
* glock. That is ok provided all granted local locks are deferred, but
* it also means that it is possible to encounter pages which are
* cached and possibly also mapped. So here we check for that and sort
* them out ahead of the dio. The glock state machine will take care of
* everything else.
*
* If in fact the cached glock state (gl->gl_state) is deferred (CW) in
* the first place, mapping->nr_pages will always be zero.
*/
if (mapping->nrpages) {
loff_t lstart = offset & (PAGE_CACHE_SIZE - 1);
loff_t len = iov_length(iov, nr_segs);
loff_t end = PAGE_ALIGN(offset + len) - 1;
rv = 0;
if (len == 0)
goto out;
if (test_and_clear_bit(GIF_SW_PAGED, &ip->i_flags))
unmap_shared_mapping_range(ip->i_inode.i_mapping, offset, len);
rv = filemap_write_and_wait_range(mapping, lstart, end);
if (rv)
return rv;
truncate_inode_pages_range(mapping, lstart, end);
}
rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs, gfs2_get_block_direct,
NULL, NULL, 0);

View File

@@ -1317,8 +1317,18 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags,
if (IS_ERR(s))
goto error_bdev;
if (s->s_root)
if (s->s_root) {
/*
* s_umount nests inside bd_mutex during
* __invalidate_device(). blkdev_put() acquires
* bd_mutex and can't be called under s_umount. Drop
* s_umount temporarily. This is safe as we're
* holding an active reference.
*/
up_write(&s->s_umount);
blkdev_put(bdev, mode);
down_write(&s->s_umount);
}
memset(&args, 0, sizeof(args));
args.ar_quota = GFS2_QUOTA_DEFAULT;