NFS: A few small NFSv4 cleanups
Subsystems (2)
cover NFS: A few small NFSv4 cleanups
From: Anna Schumaker <[email protected]>
These patches are a few cleanups I noticed while poking through the code. The first two move calls to nfs4_state_protect() into the v4 module and the last three are cleanups to the nfs4_call_sync() process.
Thoughts?
Anna
Anna Schumaker (5):
NFS: Move call to nfs4_state_protect_write() to nfs4_write_setup()
NFS: Move call to nfs4_state_protect() to nfs4_commit_setup()
NFS: Pass "privileged" value to nfs4_init_sequence()
NFS: Pass "privileged" value to nfs4_call_sync()
NFS: Combine nfs4_call_sync() with nfs4_call_sync_sequence()
fs/nfs/nfs3proc.c | 6 +- fs/nfs/nfs42proc.c | 10 +-- fs/nfs/nfs4_fs.h | 4 +- fs/nfs/nfs4proc.c | 174 +++++++++++++++++----------------------- fs/nfs/proc.c | 6 +- fs/nfs/write.c | 10 +-- include/linux/nfs_xdr.h | 6 +- 7 files changed, 94 insertions(+), 122 deletions(-)
Signature · 1 line
2.17.0
PATCH 1/5 NFS: Move call to nfs4_state_protect_write() to nfs4_write_setup()
From: Anna Schumaker <[email protected]>
This doesn't really need to be in the generic NFS client code, and I think it makes more sense to keep the v4 code in one place.
--- fs/nfs/nfs3proc.c | 3 ++- fs/nfs/nfs4proc.c | 4 +++- fs/nfs/proc.c | 3 ++- fs/nfs/write.c | 5 +---- include/linux/nfs_xdr.h | 3 ++- 5 files changed, 10 insertions(+), 8 deletions(-)
fs/nfs/nfs3proc.c +2 -1
@@ -823,7 +823,8 @@ static int nfs3_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr) }static void nfs3_proc_write_setup (struct nfs_pgio_header *hdr, -struct rpc_message *msg) +struct rpc_message *msg, +struct rpc_clnt **clnt) { msg->rpc_proc = &nfs3_procedures[NFS3PROC_WRITE ]; }
fs/nfs/nfs4proc.c +3 -1
@@ -4979,7 +4979,8 @@ bool nfs4_write_need_cache_consistency_data(struct nfs_pgio_header *hdr) }static void nfs4_proc_write_setup (struct nfs_pgio_header *hdr, -struct rpc_message *msg) +struct rpc_message *msg, +struct rpc_clnt **clnt) {struct nfs_server *server =NFS_SERVER (hdr->inode);
@@ -4996,6 +4997,7 @@ static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr, msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_WRITE ];nfs4_init_sequence (&hdr->args.seq_args, &hdr->res.seq_res,1 ); +nfs4_state_protect_write (server->nfs_client, clnt, msg, hdr); }static void nfs4_proc_commit_rpc_prepare (struct rpc_task *task,struct nfs_commit_data *data)
fs/nfs/proc.c +2 -1
@@ -618,7 +618,8 @@ static int nfs_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr) }static void nfs_proc_write_setup (struct nfs_pgio_header *hdr, -struct rpc_message *msg) +struct rpc_message *msg, +struct rpc_clnt **clnt) {/* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */ hdr->args.stable =NFS_FILE_SYNC ;
fs/nfs/write.c +1 -4
@@ -1375,12 +1375,9 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr,int priority =flush_task_priority (how); task_setup_data->priority = priority; - rpc_ops->write_setup (hdr, msg); + rpc_ops->write_setup (hdr, msg, &task_setup_data->rpc_client);trace_nfs_initiate_write (hdr->inode, hdr->io_start, hdr->good_bytes, hdr->args.stable); - -nfs4_state_protect_write (NFS_SERVER (hdr->inode)->nfs_client, - &task_setup_data->rpc_client, msg, hdr); }/* If a nfs_flush_* function fails, it should remove reqs from @head and
include/linux/nfs_xdr.h +2 -1
@@ -1620,7 +1620,8 @@ struct nfs_rpc_ops { struct nfs_pgio_header *);void (*read_setup)(struct nfs_pgio_header *,struct rpc_message *);int (*read_done)(struct rpc_task *,struct nfs_pgio_header *); -void (*write_setup)(struct nfs_pgio_header *,struct rpc_message *); +void (*write_setup)(struct nfs_pgio_header *,struct rpc_message *, +struct rpc_clnt **);int (*write_done)(struct rpc_task *,struct nfs_pgio_header *);void (*commit_setup) (struct nfs_commit_data *,struct rpc_message *);void (*commit_rpc_prepare)(struct rpc_task *,struct nfs_commit_data *);
Signature · 1 line
2.17.0
PATCH 2/5 NFS: Move call to nfs4_state_protect() to nfs4_commit_setup()
In reply to [email protected]From: Anna Schumaker <[email protected]>
Rather than doing this in the generic NFS client code. Let's put this with the other v4 stuff so it's all in one place.
--- fs/nfs/nfs3proc.c | 3 ++- fs/nfs/nfs4proc.c | 4 +++- fs/nfs/proc.c | 3 ++- fs/nfs/write.c | 5 +---- include/linux/nfs_xdr.h | 3 ++- 5 files changed, 10 insertions(+), 8 deletions(-)
fs/nfs/nfs3proc.c +2 -1
@@ -845,7 +845,8 @@ static int nfs3_commit_done(struct rpc_task *task, struct nfs_commit_data *data)return 0 ; } -static void nfs3_proc_commit_setup (struct nfs_commit_data *data,struct rpc_message *msg) +static void nfs3_proc_commit_setup (struct nfs_commit_data *data,struct rpc_message *msg, +struct rpc_clnt **clnt) { msg->rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT ]; }
fs/nfs/nfs4proc.c +3 -1
@@ -5028,7 +5028,8 @@ static int nfs4_commit_done(struct rpc_task *task, struct nfs_commit_data *data)return data->commit_done_cb (task, data); } -static void nfs4_proc_commit_setup (struct nfs_commit_data *data,struct rpc_message *msg) +static void nfs4_proc_commit_setup (struct nfs_commit_data *data,struct rpc_message *msg, +struct rpc_clnt **clnt) {struct nfs_server *server =NFS_SERVER (data->inode);
@@ -5037,6 +5038,7 @@ static void nfs4_proc_commit_setup(struct nfs_commit_data *data, struct rpc_mess data->res.server = server; msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COMMIT ];nfs4_init_sequence (&data->args.seq_args, &data->res.seq_res,1 ); +nfs4_state_protect (server->nfs_client,NFS_SP4_MACH_CRED_COMMIT , clnt, msg); }struct nfs4_renewdata {
fs/nfs/proc.c +2 -1
@@ -632,7 +632,8 @@ static void nfs_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit }static void -nfs_proc_commit_setup (struct nfs_commit_data *data,struct rpc_message *msg) +nfs_proc_commit_setup (struct nfs_commit_data *data,struct rpc_message *msg, +struct rpc_clnt **clnt) {BUG (); }
fs/nfs/write.c +1 -4
@@ -1666,14 +1666,11 @@ int nfs_initiate_commit(struct rpc_clnt *clnt, struct nfs_commit_data *data, .priority = priority, };/* Set up the initial task struct. */ - nfs_ops->commit_setup (data, &msg); + nfs_ops->commit_setup (data, &msg, &task_setup_data.rpc_client);trace_nfs_initiate_commit (data);dprintk ("NFS: initiated commit call\n" ); -nfs4_state_protect (NFS_SERVER (data->inode)->nfs_client, -NFS_SP4_MACH_CRED_COMMIT , &task_setup_data.rpc_client, &msg); - task =rpc_run_task (&task_setup_data);if (IS_ERR (task))return PTR_ERR (task);
include/linux/nfs_xdr.h +2 -1
@@ -1623,7 +1623,8 @@ struct nfs_rpc_ops {void (*write_setup)(struct nfs_pgio_header *,struct rpc_message *,struct rpc_clnt **);int (*write_done)(struct rpc_task *,struct nfs_pgio_header *); -void (*commit_setup) (struct nfs_commit_data *,struct rpc_message *); +void (*commit_setup) (struct nfs_commit_data *,struct rpc_message *, +struct rpc_clnt **);void (*commit_rpc_prepare)(struct rpc_task *,struct nfs_commit_data *);int (*commit_done) (struct rpc_task *,struct nfs_commit_data *);int (*lock)(struct file *,int ,struct file_lock *);
Signature · 1 line
2.17.0
PATCH 3/5 NFS: Pass "privileged" value to nfs4_init_sequence()
In reply to [email protected]From: Anna Schumaker <[email protected]>
We currently have a separate function just to set this, but I think it makes more sense to set it at the same time as the other values in nfs4_init_sequence()
--- fs/nfs/nfs42proc.c | 2 +- fs/nfs/nfs4_fs.h | 2 +- fs/nfs/nfs4proc.c | 81 ++++++++++++++++++---------------------------- 3 files changed, 33 insertions(+), 52 deletions(-)
fs/nfs/nfs42proc.c +1 -1
@@ -462,7 +462,7 @@ int nfs42_proc_layoutstats_generic(struct nfs_server *server,nfs42_layoutstat_release (data);return -EAGAIN ; } -nfs4_init_sequence (&data->args.seq_args, &data->res.seq_res,0 ); +nfs4_init_sequence (&data->args.seq_args, &data->res.seq_res,0 ,0 ); task =rpc_run_task (&task_setup);if (IS_ERR (task))return PTR_ERR (task);
fs/nfs/nfs4_fs.h +1 -1
@@ -251,7 +251,7 @@ extern int nfs4_handle_exception(struct nfs_server *, int, struct nfs4_exceptionextern int nfs4_call_sync (struct rpc_clnt *,struct nfs_server *,struct rpc_message *,struct nfs4_sequence_args *,struct nfs4_sequence_res *,int ); -extern void nfs4_init_sequence (struct nfs4_sequence_args *,struct nfs4_sequence_res *,int ); +extern void nfs4_init_sequence (struct nfs4_sequence_args *,struct nfs4_sequence_res *,int ,int );extern int nfs4_proc_setclientid (struct nfs_client *,u32 ,unsigned short ,struct rpc_cred *,struct nfs4_setclientid_res *);extern int nfs4_proc_setclientid_confirm (struct nfs_client *,struct nfs4_setclientid_res *arg,struct rpc_cred *);extern int nfs4_proc_get_rootfh (struct nfs_server *,struct nfs_fh *,struct nfs_fsinfo *,bool );
fs/nfs/nfs4proc.c +31 -50
261 lines not on this page · raw message
Signature · 1 line
2.17.0
PATCH 4/5 NFS: Pass "privileged" value to nfs4_call_sync()
In reply to [email protected]From: Anna Schumaker <[email protected]>
This lets us convert a few other users of synchronous RPC calls to the nfs4_call_sync() function.
--- fs/nfs/nfs42proc.c | 8 ++--- fs/nfs/nfs4_fs.h | 2 +- fs/nfs/nfs4proc.c | 78 ++++++++++++++++++++++------------------------ 3 files changed, 42 insertions(+), 46 deletions(-)
fs/nfs/nfs42proc.c +4 -4
@@ -47,7 +47,7 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,return -ENOMEM ; status =nfs4_call_sync (server->client, server, msg, - &args.seq_args, &res.seq_res,0 ); + &args.seq_args, &res.seq_res,0 ,0 );if (status ==0 ) status =nfs_post_op_update_inode (inode, res.falloc_fattr);
@@ -172,7 +172,7 @@ static ssize_t _nfs42_proc_copy(struct file *src,if (!res->commit_res.verf)return -ENOMEM ; status =nfs4_call_sync (server->client, server, &msg, - &args->seq_args, &res->seq_res,0 ); + &args->seq_args, &res->seq_res,0 ,0 );if (status == -ENOTSUPP ) server->caps &= ~NFS_CAP_COPY ;if (status)
@@ -297,7 +297,7 @@ static loff_t _nfs42_proc_llseek(struct file *filep,return status; status =nfs4_call_sync (server->client, server, &msg, - &args.seq_args, &res.seq_res,0 ); + &args.seq_args, &res.seq_res,0 ,0 );if (status == -ENOTSUPP ) server->caps &= ~NFS_CAP_SEEK ;if (status)
@@ -509,7 +509,7 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,return -ENOMEM ; status =nfs4_call_sync (server->client, server, msg, - &args.seq_args, &res.seq_res,0 ); + &args.seq_args, &res.seq_res,0 ,0 );if (status ==0 ) status =nfs_post_op_update_inode (dst_inode, res.dst_fattr);
fs/nfs/nfs4_fs.h +1 -1
@@ -250,7 +250,7 @@ int nfs4_replace_transport(struct nfs_server *server,extern int nfs4_handle_exception (struct nfs_server *,int ,struct nfs4_exception *);extern int nfs4_call_sync (struct rpc_clnt *,struct nfs_server *,struct rpc_message *,struct nfs4_sequence_args *, -struct nfs4_sequence_res *,int ); +struct nfs4_sequence_res *,int ,int );extern void nfs4_init_sequence (struct nfs4_sequence_args *,struct nfs4_sequence_res *,int ,int );extern int nfs4_proc_setclientid (struct nfs_client *,u32 ,unsigned short ,struct rpc_cred *,struct nfs4_setclientid_res *);extern int nfs4_proc_setclientid_confirm (struct nfs_client *,struct nfs4_setclientid_res *arg,struct rpc_cred *);
fs/nfs/nfs4proc.c +37 -41
259 lines not on this page · raw message
Signature · 1 line
2.17.0
Re: [PATCH 4/5] NFS: Pass "privileged" value to nfs4_call_sync()
T24gRnJpLCAyMDE4LTA1LTA0IGF0IDE2OjIyIC0wNDAwLCBzY2h1bWFrZXIuYW5uYUBnbWFpbC5j b20gd3JvdGU6DQo+IEZyb206IEFubmEgU2NodW1ha2VyIDxBbm5hLlNjaHVtYWtlckBOZXRhcHAu Y29tPg0KPiANCj4gVGhpcyBsZXRzIHVzIGNvbnZlcnQgYSBmZXcgb3RoZXIgdXNlcnMgb2Ygc3lu Y2hyb25vdXMgUlBDIGNhbGxzIHRvDQo+IHRoZQ0KPiBuZnM0X2NhbGxfc3luYygpIGZ1bmN0aW9u Lg0KPiANCj4gU2lnbmVkLW9mZi1ieTogQW5uYSBTY2h1bWFrZXIgPEFubmEuU2NodW1ha2VyQE5l dGFwcC5jb20+DQo+IC0tLQ0KPiAgZnMvbmZzL25mczQycHJvYy5jIHwgIDggKystLS0NCj4gIGZz L25mcy9uZnM0X2ZzLmggICB8ICAyICstDQo+ICBmcy9uZnMvbmZzNHByb2MuYyAgfCA3OCArKysr KysrKysrKysrKysrKysrKysrLS0tLS0tLS0tLS0tLS0tLS0tLS0NCj4gLS0tLQ0KPiAgMyBmaWxl cyBjaGFuZ2VkLCA0MiBpbnNlcnRpb25zKCspLCA0NiBkZWxldGlvbnMoLSkNCj4gDQo+IGRpZmYg LS1naXQgYS9mcy9uZnMvbmZzNDJwcm9jLmMgYi9mcy9uZnMvbmZzNDJwcm9jLmMNCj4gaW5kZXgg NGQ0YTNkZjI4Nzc5Li43ZTlhMjA4OTQwZTIgMTAwNjQ0DQo+IC0tLSBhL2ZzL25mcy9uZnM0MnBy b2MuYw0KPiArKysgYi9mcy9uZnMvbmZzNDJwcm9jLmMNCj4gQEAgLTQ3LDcgKzQ3LDcgQEAgc3Rh dGljIGludCBfbmZzNDJfcHJvY19mYWxsb2NhdGUoc3RydWN0IHJwY19tZXNzYWdlDQo+ICptc2cs IHN0cnVjdCBmaWxlICpmaWxlcCwNCj4gIAkJcmV0dXJuIC1FTk9NRU07DQo+ICANCj4gIAlzdGF0 dXMgPSBuZnM0X2NhbGxfc3luYyhzZXJ2ZXItPmNsaWVudCwgc2VydmVyLCBtc2csDQo+IC0JCQkJ JmFyZ3Muc2VxX2FyZ3MsICZyZXMuc2VxX3JlcywgMCk7DQo+ICsJCQkJJmFyZ3Muc2VxX2FyZ3Ms ICZyZXMuc2VxX3JlcywgMCwgMCk7DQoNClRoaXMgaXMgZ2V0dGluZyBvdmVybHkgY29tcGxpY2F0 ZWQuIE5vdGUgdGhhdCB0aGUgY29tbW9uIGNhc2UgdXNlcnMgYXJlDQphbGwgc2V0dGluZyB0aGUg bmV3IGFyZ3VtZW50IHRvICcwJy4NCg0KSSdtIGhhcHBpZXIgaWYgd2UgbGV0IHRoZSBwcml2aWxl Z2VkIGNhbGxzIHN0YW5kIG91dCwgc28gdGhhdCB3ZSBjYW4NCmRpc3Rpbmd1aXNoIHRoZW0gZnJv bSB0aGUgY3Jvd2QuDQoNCi0tIA0KVHJvbmQgTXlrbGVidXN0DQpDVE8sIEhhbW1lcnNwYWNlIElu Yw0KNDMwMCBFbCBDYW1pbm8gUmVhbCwgU3VpdGUgMTA1DQpMb3MgQWx0b3MsIENBIDk0MDIyDQp3 d3cuaGFtbWVyLnNwYWNlIGlkPSIteC1ldm8tc2VsZWN0aW9uLWVuZC1tYXJrZXIiPg==
PATCH 5/5 NFS: Combine nfs4_call_sync() with nfs4_call_sync_sequence()
In reply to [email protected]From: Anna Schumaker <[email protected]>
The nfs4_call_sync_sequence() version only hase a single user, nfs4_call_sync(), so let's just add in a call to nfs4_init_sequence() instead of needing to have another function just to do this.
--- fs/nfs/nfs4proc.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-)
fs/nfs/nfs4proc.c +8 -17
@@ -993,11 +993,13 @@ static const struct rpc_call_ops nfs40_call_sync_ops = { .rpc_call_done = nfs40_call_sync_done, }; -static int nfs4_call_sync_sequence (struct rpc_clnt *clnt, -struct nfs_server *server, -struct rpc_message *msg, -struct nfs4_sequence_args *args, -struct nfs4_sequence_res *res) +int nfs4_call_sync (struct rpc_clnt *clnt, +struct nfs_server *server, +struct rpc_message *msg, +struct nfs4_sequence_args *args, +struct nfs4_sequence_res *res, +int cache_reply, +int privileged) {int ret;struct rpc_task *task;
@@ -1014,6 +1016,7 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt, .callback_data = &data }; +nfs4_init_sequence (args, res, cache_reply, privileged); task =rpc_run_task (&task_setup);if (IS_ERR (task)) ret =PTR_ERR (task);
@@ -1024,18 +1027,6 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,return ret; } -int nfs4_call_sync (struct rpc_clnt *clnt, -struct nfs_server *server, -struct rpc_message *msg, -struct nfs4_sequence_args *args, -struct nfs4_sequence_res *res, -int cache_reply, -int privileged) -{ -nfs4_init_sequence (args, res, cache_reply, privileged); -return nfs4_call_sync_sequence (clnt, server, msg, args, res); -} -static void update_changeattr (struct inode *dir,struct nfs4_change_info *cinfo,unsigned long timestamp) {
Signature · 1 line
2.17.0
Re: [PATCH 5/5] NFS: Combine nfs4_call_sync() with nfs4_call_sync_sequence()
T24gRnJpLCAyMDE4LTA1LTA0IGF0IDE2OjIyIC0wNDAwLCBzY2h1bWFrZXIuYW5uYUBnbWFpbC5j b20gd3JvdGU6DQo+IEZyb206IEFubmEgU2NodW1ha2VyIDxBbm5hLlNjaHVtYWtlckBOZXRhcHAu Y29tPg0KPiANCj4gVGhlIG5mczRfY2FsbF9zeW5jX3NlcXVlbmNlKCkgdmVyc2lvbiBvbmx5IGhh c2UgYSBzaW5nbGUgdXNlciwNCj4gbmZzNF9jYWxsX3N5bmMoKSwgc28gbGV0J3MganVzdCBhZGQg aW4gYSBjYWxsIHRvIG5mczRfaW5pdF9zZXF1ZW5jZSgpDQo+IGluc3RlYWQgb2YgbmVlZGluZyB0 byBoYXZlIGFub3RoZXIgZnVuY3Rpb24ganVzdCB0byBkbyB0aGlzLg0KPiANCj4gU2lnbmVkLW9m Zi1ieTogQW5uYSBTY2h1bWFrZXIgPEFubmEuU2NodW1ha2VyQE5ldGFwcC5jb20+DQo+IC0tLQ0K PiAgZnMvbmZzL25mczRwcm9jLmMgfCAyNSArKysrKysrKy0tLS0tLS0tLS0tLS0tLS0tDQo+ICAx IGZpbGUgY2hhbmdlZCwgOCBpbnNlcnRpb25zKCspLCAxNyBkZWxldGlvbnMoLSkNCj4gDQo+IGRp ZmYgLS1naXQgYS9mcy9uZnMvbmZzNHByb2MuYyBiL2ZzL25mcy9uZnM0cHJvYy5jDQo+IGluZGV4 IDUwNWY2MDVkY2FjMi4uOTlkNzdmNmU3ZTQwIDEwMDY0NA0KPiAtLS0gYS9mcy9uZnMvbmZzNHBy b2MuYw0KPiArKysgYi9mcy9uZnMvbmZzNHByb2MuYw0KPiBAQCAtOTkzLDExICs5OTMsMTMgQEAg c3RhdGljIGNvbnN0IHN0cnVjdCBycGNfY2FsbF9vcHMNCj4gbmZzNDBfY2FsbF9zeW5jX29wcyA9 IHsNCj4gIAkucnBjX2NhbGxfZG9uZSA9IG5mczQwX2NhbGxfc3luY19kb25lLA0KPiAgfTsNCj4g IA0KPiAtc3RhdGljIGludCBuZnM0X2NhbGxfc3luY19zZXF1ZW5jZShzdHJ1Y3QgcnBjX2NsbnQg KmNsbnQsDQo+IC0JCQkJICAgc3RydWN0IG5mc19zZXJ2ZXIgKnNlcnZlciwNCj4gLQkJCQkgICBz dHJ1Y3QgcnBjX21lc3NhZ2UgKm1zZywNCj4gLQkJCQkgICBzdHJ1Y3QgbmZzNF9zZXF1ZW5jZV9h cmdzICphcmdzLA0KPiAtCQkJCSAgIHN0cnVjdCBuZnM0X3NlcXVlbmNlX3JlcyAqcmVzKQ0KPiAr aW50IG5mczRfY2FsbF9zeW5jKHN0cnVjdCBycGNfY2xudCAqY2xudCwNCj4gKwkJICAgc3RydWN0 IG5mc19zZXJ2ZXIgKnNlcnZlciwNCj4gKwkJICAgc3RydWN0IHJwY19tZXNzYWdlICptc2csDQo+ ICsJCSAgIHN0cnVjdCBuZnM0X3NlcXVlbmNlX2FyZ3MgKmFyZ3MsDQo+ICsJCSAgIHN0cnVjdCBu ZnM0X3NlcXVlbmNlX3JlcyAqcmVzLA0KPiArCQkgICBpbnQgY2FjaGVfcmVwbHksDQo+ICsJCSAg IGludCBwcml2aWxlZ2VkKQ0KDQoNCkhtbS4uLi4gNyBmdW5jdGlvbiBhcmd1bWVudHM/IFRoYXQn cyBhbG1vc3QgZGVzZXJ2aW5nIG9mIGl0cyBvd24NCnN0cnVjdHVyZS4uLg0KDQpMZXQncyBub3Qg Z28gZG93biB0aGlzIHBhdGguIEl0J3MgZWFzaWVyIHRvIGluaXRpYWxpc2UgdGhlIHNlcXVlbmNl DQphcmdzL3JlcyBmaXJzdCwgYW5kIHRoYXQgaXMgcHJlY2lzZWx5IHdoeSBJIGNob3NlIHRvIGRv IHRoaW5ncyB0aGUgd2F5DQp0aGV5IGFyZSB0b2RheS4NCg0KLS0gDQpUcm9uZCBNeWtsZWJ1c3QN CkNUTywgSGFtbWVyc3BhY2UgSW5jDQo0MzAwIEVsIENhbWlubyBSZWFsLCBTdWl0ZSAxMDUNCkxv cyBBbHRvcywgQ0EgOTQwMjINCnd3dy5oYW1tZXIuc3BhY2UgaWQ9Ii14LWV2by1zZWxlY3Rpb24t ZW5kLW1hcmtlciI+