Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 884416 Details for
Bug 1085425
Input/Output Errors with 64bit Server and 32bit client
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Rebase of http://review.gluster.org/7278 to 3.4.2
0001-fuse-prevent-READDIR-P-from-writing-to-much-data-to-.patch (text/plain), 7.40 KB, created by
Niels de Vos
on 2014-04-09 08:06:43 UTC
(
hide
)
Description:
Rebase of http://review.gluster.org/7278 to 3.4.2
Filename:
MIME Type:
Creator:
Niels de Vos
Created:
2014-04-09 08:06:43 UTC
Size:
7.40 KB
patch
obsolete
>From 5a38438da3aad788b0b5087f1f41edfeec5febc1 Mon Sep 17 00:00:00 2001 >From: Niels de Vos <ndevos@redhat.com> >Date: Wed, 9 Apr 2014 09:32:28 +0200 >Subject: [PATCH] fuse: prevent READDIR(P) from writing to much data to /dev/fuse > >[3.4.2 edition for ceiphas in #gluster] > >In an environment with mixed architectures (32-bit servers, 64-bit >client), it is possible that the on-wire Reply on a READDIR(P) procedure >contains more direntries than the client can fit in the maximum size >that the fuse-request indicated. > >A direntry is a dynamically sized structure, because the structure >contains the name of the entry. The client sends a maximum size in the >READDIR(P) Call to the server, and the server uses this size to limit >the number of direntries to return. In case the server can pack more >direntries in the requested maximum size (due to alignment differences >between the architectures), it can happen that the client unpacks the >list of direntries into a buffer that exceeds the maximum size that was >given in the initial fuse-request. > >This change introduces a check for the maximum requested size of the >fuse-response in fuse_readdir_cbk() and fuse_readdirp_cbk(). When the >conversion from gluster-direntries to the fuse-direntry format takes >place, the maximum size is checked, and the 'extra' direntries are >discarded. The next readdir()/getdents() that is done, will fetch the >just discarded direntries again. > >In addition to this bugfix, some extra logging in send_fuse_iov() and >send_fuse_data() has been added to help diagnosing similar issues. > >> Change-Id-in-master: If2eecfcdf9c248f3820035601446d2c89ff9d1a1 >Change-Id: I4b379d94a12a8b18ccad765ddcfe9f7cbb48cb10 >BUG: 1074023 >Signed-off-by: Niels de Vos <ndevos@redhat.com> >--- > xlators/mount/fuse/src/fuse-bridge.c | 58 +++++++++++++++++++++++++-------- > 1 files changed, 44 insertions(+), 14 deletions(-) > >diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c >index e9c5383..3d4de1c 100644 >--- a/xlators/mount/fuse/src/fuse-bridge.c >+++ b/xlators/mount/fuse/src/fuse-bridge.c >@@ -184,6 +184,7 @@ send_fuse_iov (xlator_t *this, fuse_in_header_t *finh, struct iovec *iov_out, > fouh->unique = finh->unique; > > res = writev (priv->fd, iov_out, count); >+ gf_log ("glusterfs-fuse", GF_LOG_TRACE, "writev() result %d/%d %s", res, fouh->len, res == -1 ? strerror (errno) : ""); > > if (res == -1) > return errno; >@@ -213,13 +214,18 @@ send_fuse_data (xlator_t *this, fuse_in_header_t *finh, void *data, size_t size) > { > struct fuse_out_header fouh = {0, }; > struct iovec iov_out[2]; >+ int ret = 0; > > fouh.error = 0; > iov_out[0].iov_base = &fouh; > iov_out[1].iov_base = data; > iov_out[1].iov_len = size; > >- return send_fuse_iov (this, finh, iov_out, 2); >+ ret = send_fuse_iov (this, finh, iov_out, 2); >+ if (ret != 0) >+ gf_log ("glusterfs-fuse", GF_LOG_ERROR, "send_fuse_iov() failed: %s", strerror (ret)); >+ >+ return ret; > } > > #define send_fuse_obj(this, finh, obj) \ >@@ -2468,6 +2474,7 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, > fuse_state_t *state = NULL; > fuse_in_header_t *finh = NULL; > int size = 0; >+ int max_size = 0; > char *buf = NULL; > gf_dirent_t *entry = NULL; > struct fuse_dirent *fde = NULL; >@@ -2493,16 +2500,23 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, > frame->root->unique, op_ret, state->size, state->off); > > list_for_each_entry (entry, &entries->list, list) { >- size += FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET + >- strlen (entry->d_name)); >+ max_size += FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET + >+ strlen (entry->d_name)); >+ >+ if (max_size > state->size) { >+ /* we received to many entries to fit in the request */ >+ max_size -= FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET + >+ strlen (entry->d_name)); >+ break; >+ } > } > >- if (size <= 0) { >- send_fuse_data (this, finh, 0, 0); >- goto out; >- } >+ if (max_size <= 0) { >+ send_fuse_data (this, finh, 0, 0); >+ goto out; >+ } > >- buf = GF_CALLOC (1, size, gf_fuse_mt_char); >+ buf = GF_CALLOC (1, max_size, gf_fuse_mt_char); > if (!buf) { > gf_log ("glusterfs-fuse", GF_LOG_DEBUG, > "%"PRIu64": READDIR => -1 (%s)", frame->root->unique, >@@ -2516,6 +2530,9 @@ fuse_readdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, > fde = (struct fuse_dirent *)(buf + size); > gf_fuse_fill_dirent (entry, fde, priv->enable_ino32); > size += FUSE_DIRENT_SIZE (fde); >+ >+ if (size == max_size) >+ break; > } > > send_fuse_data (this, finh, buf, size); >@@ -2569,6 +2586,7 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, > { > fuse_state_t *state = NULL; > fuse_in_header_t *finh = NULL; >+ int max_size = 0; > int size = 0; > char *buf = NULL; > gf_dirent_t *entry = NULL; >@@ -2594,16 +2612,24 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, > frame->root->unique, op_ret, state->size, state->off); > > list_for_each_entry (entry, &entries->list, list) { >- size += FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET_DIRENTPLUS + >- strlen (entry->d_name)); >+ max_size += FUSE_DIRENT_ALIGN (FUSE_NAME_OFFSET_DIRENTPLUS + >+ strlen (entry->d_name)); >+ >+ if (max_size > state->size) { >+ /* we received to many entries to fit in the reply */ >+ max_size -= FUSE_DIRENT_ALIGN ( >+ FUSE_NAME_OFFSET_DIRENTPLUS + >+ strlen (entry->d_name)); >+ break; >+ } > } > >- if (size <= 0) { >+ if (max_size <= 0) { > send_fuse_data (this, finh, 0, 0); > goto out; > } > >- buf = GF_CALLOC (1, size, gf_fuse_mt_char); >+ buf = GF_CALLOC (1, max_size, gf_fuse_mt_char); > if (!buf) { > gf_log ("glusterfs-fuse", GF_LOG_DEBUG, > "%"PRIu64": READDIRP => -1 (%s)", frame->root->unique, >@@ -2626,7 +2652,7 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, > size += FUSE_DIRENTPLUS_SIZE (fde); > > if (!entry->inode) >- continue; >+ goto next_entry; > > entry->d_stat.ia_blksize = this->ctx->page_size; > gf_fuse_stat2attr (&entry->d_stat, &feo->attr, priv->enable_ino32); >@@ -2634,7 +2660,7 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, > linked_inode = inode_link (entry->inode, state->fd->inode, > entry->d_name, &entry->d_stat); > if (!linked_inode) >- continue; >+ goto next_entry; > > inode_lookup (linked_inode); > >@@ -2652,6 +2678,10 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, > calc_timeout_sec (priv->attribute_timeout); > feo->attr_valid_nsec = > calc_timeout_nsec (priv->attribute_timeout); >+ >+next_entry: >+ if (size == max_size) >+ break; > } > > send_fuse_data (this, finh, buf, size); >-- >1.7.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1085425
: 884416