Skip to content

Commit ec4b092

Browse files
olgakorn1Olga Kornievskaia
authored andcommitted
NFS: inter ssc open
NFSv4.2 inter server to server copy requires the destination server to READ the data from the source server using the provided stateid and file handle. Given an NFSv4 stateid and filehandle from the COPY operaion, provide the destination server with an NFS client function to create a struct file suitable for the destiniation server to READ the data to be copied. Signed-off-by: Olga Kornievskaia <[email protected]> Signed-off-by: Andy Adamson <[email protected]>
1 parent 1d38f3f commit ec4b092

File tree

3 files changed

+103
-3
lines changed

3 files changed

+103
-3
lines changed

fs/nfs/nfs4_fs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,13 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
311311
const struct nfs_open_context *ctx,
312312
const struct nfs_lock_context *l_ctx,
313313
fmode_t fmode);
314+
extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
315+
struct nfs_fattr *fattr, struct nfs4_label *label,
316+
struct inode *inode);
317+
extern int update_open_stateid(struct nfs4_state *state,
318+
const nfs4_stateid *open_stateid,
319+
const nfs4_stateid *deleg_stateid,
320+
fmode_t fmode);
314321

315322
extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
316323
struct nfs_fsinfo *fsinfo);

fs/nfs/nfs4file.c

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/file.h>
99
#include <linux/falloc.h>
1010
#include <linux/nfs_fs.h>
11+
#include <linux/file.h>
1112
#include "delegation.h"
1213
#include "internal.h"
1314
#include "iostat.h"
@@ -286,6 +287,99 @@ static loff_t nfs42_remap_file_range(struct file *src_file, loff_t src_off,
286287
out:
287288
return ret < 0 ? ret : count;
288289
}
290+
291+
static int read_name_gen = 1;
292+
#define SSC_READ_NAME_BODY "ssc_read_%d"
293+
294+
struct file *
295+
nfs42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh,
296+
nfs4_stateid *stateid)
297+
{
298+
struct nfs_fattr fattr;
299+
struct file *filep, *res;
300+
struct nfs_server *server;
301+
struct inode *r_ino = NULL;
302+
struct nfs_open_context *ctx;
303+
struct nfs4_state_owner *sp;
304+
char *read_name;
305+
int len, status = 0;
306+
307+
server = NFS_SERVER(ss_mnt->mnt_root->d_inode);
308+
309+
nfs_fattr_init(&fattr);
310+
311+
status = nfs4_proc_getattr(server, src_fh, &fattr, NULL, NULL);
312+
if (status < 0) {
313+
res = ERR_PTR(status);
314+
goto out;
315+
}
316+
317+
res = ERR_PTR(-ENOMEM);
318+
len = strlen(SSC_READ_NAME_BODY) + 16;
319+
read_name = kzalloc(len, GFP_NOFS);
320+
if (read_name == NULL)
321+
goto out;
322+
snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++);
323+
324+
r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, &fattr,
325+
NULL);
326+
if (IS_ERR(r_ino)) {
327+
res = ERR_CAST(r_ino);
328+
goto out;
329+
}
330+
331+
filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, FMODE_READ,
332+
r_ino->i_fop);
333+
if (IS_ERR(filep)) {
334+
res = ERR_CAST(filep);
335+
goto out;
336+
}
337+
filep->f_mode |= FMODE_READ;
338+
339+
ctx = alloc_nfs_open_context(filep->f_path.dentry, filep->f_mode,
340+
filep);
341+
if (IS_ERR(ctx)) {
342+
res = ERR_CAST(ctx);
343+
goto out_filep;
344+
}
345+
346+
res = ERR_PTR(-EINVAL);
347+
sp = nfs4_get_state_owner(server, ctx->cred, GFP_KERNEL);
348+
if (sp == NULL)
349+
goto out_ctx;
350+
351+
ctx->state = nfs4_get_open_state(r_ino, sp);
352+
if (ctx->state == NULL)
353+
goto out_stateowner;
354+
355+
set_bit(NFS_OPEN_STATE, &ctx->state->flags);
356+
memcpy(&ctx->state->open_stateid.other, &stateid->other,
357+
NFS4_STATEID_OTHER_SIZE);
358+
update_open_stateid(ctx->state, stateid, NULL, filep->f_mode);
359+
360+
nfs_file_set_open_context(filep, ctx);
361+
put_nfs_open_context(ctx);
362+
363+
file_ra_state_init(&filep->f_ra, filep->f_mapping->host->i_mapping);
364+
res = filep;
365+
out:
366+
return res;
367+
out_stateowner:
368+
nfs4_put_state_owner(sp);
369+
out_ctx:
370+
put_nfs_open_context(ctx);
371+
out_filep:
372+
fput(filep);
373+
goto out;
374+
}
375+
EXPORT_SYMBOL_GPL(nfs42_ssc_open);
376+
void nfs42_ssc_close(struct file *filep)
377+
{
378+
struct nfs_open_context *ctx = nfs_file_open_context(filep);
379+
380+
ctx->state->flags = 0;
381+
}
382+
EXPORT_SYMBOL_GPL(nfs42_ssc_close);
289383
#endif /* CONFIG_NFS_V4_2 */
290384

291385
const struct file_operations nfs4_file_operations = {

fs/nfs/nfs4proc.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ struct nfs4_opendata;
9191
static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
9292
static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *);
9393
static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
94-
static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label, struct inode *inode);
9594
static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode *inode);
9695
static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
9796
struct nfs_fattr *fattr, struct iattr *sattr,
@@ -1718,7 +1717,7 @@ static void nfs_state_clear_delegation(struct nfs4_state *state)
17181717
write_sequnlock(&state->seqlock);
17191718
}
17201719

1721-
static int update_open_stateid(struct nfs4_state *state,
1720+
int update_open_stateid(struct nfs4_state *state,
17221721
const nfs4_stateid *open_stateid,
17231722
const nfs4_stateid *delegation,
17241723
fmode_t fmode)
@@ -4065,7 +4064,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
40654064
return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
40664065
}
40674066

4068-
static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
4067+
int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
40694068
struct nfs_fattr *fattr, struct nfs4_label *label,
40704069
struct inode *inode)
40714070
{

0 commit comments

Comments
 (0)