Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 38403
b: refs/heads/master
c: 9334691
h: refs/heads/master
i:
  38401: f753c4a
  38399: b590829
v: v3
  • Loading branch information
Manoj Naik authored and Linus Torvalds committed Oct 4, 2006
1 parent 3fe0c50 commit 9cbc2fc
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b009a873de05c6e0d7613df3584b6dcb2e4280ee
refs/heads/master: 933469190ed5915b0568bc564346bb8db718f460
118 changes: 114 additions & 4 deletions trunk/fs/nfsd/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -319,13 +319,25 @@ svc_expkey_update(struct svc_expkey *new, struct svc_expkey *old)

static struct cache_head *export_table[EXPORT_HASHMAX];

static void nfsd4_fslocs_free(struct nfsd4_fs_locations *fsloc)
{
int i;

for (i = 0; i < fsloc->locations_count; i++) {
kfree(fsloc->locations[i].path);
kfree(fsloc->locations[i].hosts);
}
kfree(fsloc->locations);
}

static void svc_export_put(struct kref *ref)
{
struct svc_export *exp = container_of(ref, struct svc_export, h.ref);
dput(exp->ex_dentry);
mntput(exp->ex_mnt);
auth_domain_put(exp->ex_client);
kfree(exp->ex_path);
nfsd4_fslocs_free(&exp->ex_fslocs);
kfree(exp);
}

Expand Down Expand Up @@ -387,6 +399,69 @@ static int check_export(struct inode *inode, int flags)

}

#ifdef CONFIG_NFSD_V4

static int
fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
{
int len;
int migrated, i, err;

len = qword_get(mesg, buf, PAGE_SIZE);
if (len != 5 || memcmp(buf, "fsloc", 5))
return 0;

/* listsize */
err = get_int(mesg, &fsloc->locations_count);
if (err)
return err;
if (fsloc->locations_count > MAX_FS_LOCATIONS)
return -EINVAL;
if (fsloc->locations_count == 0)
return 0;

fsloc->locations = kzalloc(fsloc->locations_count
* sizeof(struct nfsd4_fs_location), GFP_KERNEL);
if (!fsloc->locations)
return -ENOMEM;
for (i=0; i < fsloc->locations_count; i++) {
/* colon separated host list */
err = -EINVAL;
len = qword_get(mesg, buf, PAGE_SIZE);
if (len <= 0)
goto out_free_all;
err = -ENOMEM;
fsloc->locations[i].hosts = kstrdup(buf, GFP_KERNEL);
if (!fsloc->locations[i].hosts)
goto out_free_all;
err = -EINVAL;
/* slash separated path component list */
len = qword_get(mesg, buf, PAGE_SIZE);
if (len <= 0)
goto out_free_all;
err = -ENOMEM;
fsloc->locations[i].path = kstrdup(buf, GFP_KERNEL);
if (!fsloc->locations[i].path)
goto out_free_all;
}
/* migrated */
err = get_int(mesg, &migrated);
if (err)
goto out_free_all;
err = -EINVAL;
if (migrated < 0 || migrated > 1)
goto out_free_all;
fsloc->migrated = migrated;
return 0;
out_free_all:
nfsd4_fslocs_free(fsloc);
return err;
}

#else /* CONFIG_NFSD_V4 */
static inline int fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) { return 0; }
#endif

static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
{
/* client path expiry [flags anonuid anongid fsid] */
Expand Down Expand Up @@ -441,6 +516,11 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
if (exp.h.expiry_time == 0)
goto out;

/* fs locations */
exp.ex_fslocs.locations = NULL;
exp.ex_fslocs.locations_count = 0;
exp.ex_fslocs.migrated = 0;

/* flags */
err = get_int(&mesg, &an_int);
if (err == -ENOENT)
Expand All @@ -466,6 +546,10 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)

err = check_export(nd.dentry->d_inode, exp.ex_flags);
if (err) goto out;

err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
if (err)
goto out;
}

expp = svc_export_lookup(&exp);
Expand All @@ -489,7 +573,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
return err;
}

static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong);
static void exp_flags(struct seq_file *m, int flag, int fsid,
uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fslocs);

static int svc_export_show(struct seq_file *m,
struct cache_detail *cd,
Expand All @@ -508,8 +593,8 @@ static int svc_export_show(struct seq_file *m,
seq_putc(m, '(');
if (test_bit(CACHE_VALID, &h->flags) &&
!test_bit(CACHE_NEGATIVE, &h->flags))
exp_flags(m, exp->ex_flags, exp->ex_fsid,
exp->ex_anon_uid, exp->ex_anon_gid);
exp_flags(m, exp->ex_flags, exp->ex_fsid,
exp->ex_anon_uid, exp->ex_anon_gid, &exp->ex_fslocs);
seq_puts(m, ")\n");
return 0;
}
Expand All @@ -532,6 +617,9 @@ static void svc_export_init(struct cache_head *cnew, struct cache_head *citem)
new->ex_dentry = dget(item->ex_dentry);
new->ex_mnt = mntget(item->ex_mnt);
new->ex_path = NULL;
new->ex_fslocs.locations = NULL;
new->ex_fslocs.locations_count = 0;
new->ex_fslocs.migrated = 0;
}

static void export_update(struct cache_head *cnew, struct cache_head *citem)
Expand All @@ -545,6 +633,12 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
new->ex_fsid = item->ex_fsid;
new->ex_path = item->ex_path;
item->ex_path = NULL;
new->ex_fslocs.locations = item->ex_fslocs.locations;
item->ex_fslocs.locations = NULL;
new->ex_fslocs.locations_count = item->ex_fslocs.locations_count;
item->ex_fslocs.locations_count = 0;
new->ex_fslocs.migrated = item->ex_fslocs.migrated;
item->ex_fslocs.migrated = 0;
}

static struct cache_head *svc_export_alloc(void)
Expand Down Expand Up @@ -1159,7 +1253,8 @@ static struct flags {
{ 0, {"", ""}}
};

static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t anong)
static void exp_flags(struct seq_file *m, int flag, int fsid,
uid_t anonu, uid_t anong, struct nfsd4_fs_locations *fsloc)
{
int first = 0;
struct flags *flg;
Expand All @@ -1175,6 +1270,21 @@ static void exp_flags(struct seq_file *m, int flag, int fsid, uid_t anonu, uid_t
seq_printf(m, "%sanonuid=%d", first++?",":"", anonu);
if (anong != (gid_t)-2 && anong != (0x10000-2))
seq_printf(m, "%sanongid=%d", first++?",":"", anong);
if (fsloc && fsloc->locations_count > 0) {
char *loctype = (fsloc->migrated) ? "refer" : "replicas";
int i;

seq_printf(m, "%s%s=", first++?",":"", loctype);
seq_escape(m, fsloc->locations[0].path, ",;@ \t\n\\");
seq_putc(m, '@');
seq_escape(m, fsloc->locations[0].hosts, ",;@ \t\n\\");
for (i = 1; i < fsloc->locations_count; i++) {
seq_putc(m, ';');
seq_escape(m, fsloc->locations[i].path, ",;@ \t\n\\");
seq_putc(m, '@');
seq_escape(m, fsloc->locations[i].hosts, ",;@ \t\n\\");
}
}
}

static int e_show(struct seq_file *m, void *p)
Expand Down
20 changes: 20 additions & 0 deletions trunk/include/linux/nfsd/export.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,25 @@

#ifdef __KERNEL__

/*
* FS Locations
*/

#define MAX_FS_LOCATIONS 128

struct nfsd4_fs_location {
char *hosts; /* colon separated list of hosts */
char *path; /* slash separated list of path components */
};

struct nfsd4_fs_locations {
uint32_t locations_count;
struct nfsd4_fs_location *locations;
/* If we're not actually serving this data ourselves (only providing a
* list of replicas that do serve it) then we set "migrated": */
int migrated;
};

struct svc_export {
struct cache_head h;
struct auth_domain * ex_client;
Expand All @@ -55,6 +74,7 @@ struct svc_export {
uid_t ex_anon_uid;
gid_t ex_anon_gid;
int ex_fsid;
struct nfsd4_fs_locations ex_fslocs;
};

/* an "export key" (expkey) maps a filehandlefragement to an
Expand Down

0 comments on commit 9cbc2fc

Please sign in to comment.