Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx> --- itm/handlers/readdir_reply_nopages.py | 86 +++++++++++++++++++++++++++++++++ 1 files changed, 86 insertions(+), 0 deletions(-) create mode 100644 itm/handlers/readdir_reply_nopages.py diff --git a/itm/handlers/readdir_reply_nopages.py b/itm/handlers/readdir_reply_nopages.py new file mode 100644 index 0000000..e5dd91e --- /dev/null +++ b/itm/handlers/readdir_reply_nopages.py @@ -0,0 +1,86 @@ +from rpc_const import * +from xdrdef.nfs4_const import * +from xdrdef.nfs4_type import * +from xdrdef.nfs3_const import * +from xdrdef.nfs3_type import * +from xdrdef.nfs3_pack import NFS3Packer, NFS3Unpacker +from nfs4commoncode import encode_status_by_name +from itm.handlers import BaseHandler + +import itm +import nfs4lib + +""" + This handler modifies the response body for a v4 READDIR call + or v3 READDIRPLUS call such that there are no pages of data in + the response. + + https://bugzilla.redhat.com/show_bug.cgi?id=1182830 + http://marc.info/?l=linux-nfs&m=142964061807798&w=2 + ce85cfb NFS: Don't attempt to decode missing directory entries +""" + +class Handler(BaseHandler): + + def will_handle(self, cb_info): + + # setup for v4: + if hasattr(cb_info, "v4_res"): + res = cb_info.v4_res; + my_ops = filter(lambda x: x.resop == OP_READDIR, res.resarray) + if not my_ops: + return 0; + + # save the resop for handle() + self.my_resop = my_ops[0] + return 1; + + # setup for v3: + msg = cb_info.rpc_msg + if msg.body.mtype == REPLY and \ + msg.body.cbody.vers == 3 and \ + msg.body.cbody.proc == NFSPROC3_READDIRPLUS: + + unpacker = NFS3Unpacker(cb_info.rpc_msg_data) + self.my_resop = unpacker.unpack_READDIRPLUS3res() + + return 1; + + return 0; + + def handle(self, cb_info): + print "readdir is returning no pages" + + msg = cb_info.rpc_msg + + if msg.body.cbody.vers == 4: + # remove whatever results were being returned so that we have a + # predictable length: + self.my_resop.opreaddir.resok4.reply = dirlist4([], eof=0) + + p = nfs4lib.FancyNFS4Packer() + p.pack_COMPOUND4res(cb_info.v4_res) + buf = p.get_buffer() + + # chop off the page data: + cb_info.rpc_msg_data = buf[:-8] + #itm.dump_data(cb_info.rpc_msg_data) + cb_info.encode_RPC() + return 1 + + elif msg.body.cbody.vers == 3: + # remove whatever results were being returned so that we have a + # predictable length: + self.my_resop.resok.reply = dirlistplus3([], eof=0) + + p = NFS3Packer() + p.pack_READDIRPLUS3res(self.my_resop) + buf = p.get_buffer() + + # chop off the page data: + cb_info.rpc_msg_data = buf[:-8] + #itm.dump_data(cb_info.rpc_msg_data) + cb_info.encode_RPC() + return 1 + + return 0 -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html