• Chuck Lever's avatar
    NFSD: da_addr_body field missing in some GETDEVICEINFO replies · 6372e2ee
    Chuck Lever authored
    The XDR specification in RFC 8881 looks like this:
    
    struct device_addr4 {
    	layouttype4	da_layout_type;
    	opaque		da_addr_body<>;
    };
    
    struct GETDEVICEINFO4resok {
    	device_addr4	gdir_device_addr;
    	bitmap4		gdir_notification;
    };
    
    union GETDEVICEINFO4res switch (nfsstat4 gdir_status) {
    case NFS4_OK:
    	GETDEVICEINFO4resok gdir_resok4;
    case NFS4ERR_TOOSMALL:
    	count4		gdir_mincount;
    default:
    	void;
    };
    
    Looking at nfsd4_encode_getdeviceinfo() ....
    
    When the client provides a zero gd_maxcount, then the Linux NFS
    server implementation encodes the da_layout_type field and then
    skips the da_addr_body field completely, proceeding directly to
    encode gdir_notification field.
    
    There does not appear to be an option in the specification to skip
    encoding da_addr_body. Moreover, Section 18.40.3 says:
    
    > If the client wants to just update or turn off notifications, it
    > MAY send a GETDEVICEINFO operation with gdia_maxcount set to zero.
    > In that event, if the device ID is valid, the reply's da_addr_body
    > field of the gdir_device_addr field will be of zero length.
    
    Since the layout drivers are responsible for encoding the
    da_addr_body field, put this fix inside the ->encode_getdeviceinfo
    methods.
    
    Fixes: 9cf514cc ("nfsd: implement pNFS operations")
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Cc: Tom Haynes <loghyr@gmail.com>
    Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
    6372e2ee
blocklayoutxdr.c 5.37 KB