Commit cea4a80b authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] kNFSd: Verify exportability when updating export cache.

The systemcall interface for adding exports checked that
the filesystem was exportable.  The new interface doesn't...

This patch splits this functionality into a separate function
which is called from both sites.
parent 51b23916
......@@ -271,6 +271,47 @@ void svc_export_request(struct cache_detail *cd,
}
static struct svc_export *svc_export_lookup(struct svc_export *, int);
extern struct dentry *
find_exported_dentry(struct super_block *sb, void *obj, void *parent,
int (*acceptable)(void *context, struct dentry *de),
void *context);
static int check_export(struct inode *inode, int flags)
{
/* We currently export only dirs and regular files.
* This is what umountd does.
*/
if (!S_ISDIR(inode->i_mode) &&
!S_ISREG(inode->i_mode))
return -ENOTDIR;
/* There are two requirements on a filesystem to be exportable.
* 1: We must be able to identify the filesystem from a number.
* either a device number (so FS_REQUIRES_DEV needed)
* or an FSID number (so NFSEXP_FSID needed).
* 2: We must be able to find an inode from a filehandle.
* This means that s_export_op must be set.
*/
if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
!(flags & NFSEXP_FSID)) {
dprintk("exp_export: export of non-dev fs without fsid");
return -EINVAL;
}
if (!inode->i_sb->s_export_op) {
dprintk("exp_export: export of invalid fs type.\n");
return -EINVAL;
}
/* Ok, we can export it */;
if (!inode->i_sb->s_export_op->find_exported_dentry)
inode->i_sb->s_export_op->find_exported_dentry =
find_exported_dentry;
return 0;
}
int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
{
/* client path expiry [flags anonuid anongid fsid] */
......@@ -342,6 +383,9 @@ int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
err = get_int(&mesg, &an_int);
if (err) goto out;
exp.ex_fsid = an_int;
err = check_export(nd.dentry->d_inode, exp.ex_flags);
if (err) goto out;
}
expp = svc_export_lookup(&exp, 1);
......@@ -594,10 +638,6 @@ static void exp_unhash(struct svc_export *exp)
svc_expkey_cache.nextcheck = get_seconds();
}
extern struct dentry *
find_exported_dentry(struct super_block *sb, void *obj, void *parent,
int (*acceptable)(void *context, struct dentry *de),
void *context);
/*
* Export a file system.
*/
......@@ -661,36 +701,8 @@ exp_export(struct nfsctl_export *nxp)
goto finish;
}
/* We currently export only dirs and regular files.
* This is what umountd does.
*/
err = -ENOTDIR;
if (!S_ISDIR(inode->i_mode) && !S_ISREG(inode->i_mode))
goto finish;
err = -EINVAL;
/* There are two requirements on a filesystem to be exportable.
* 1: We must be able to identify the filesystem from a number.
* either a device number (so FS_REQUIRES_DEV needed)
* or an FSID number (so NFSEXP_FSID needed).
* 2: We must be able to find an inode from a filehandle.
* This means that s_export_op must be set.
*/
if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV)) {
if (!(nxp->ex_flags & NFSEXP_FSID)) {
dprintk("exp_export: export of non-dev fs without fsid");
goto finish;
}
}
if (!inode->i_sb->s_export_op) {
dprintk("exp_export: export of invalid fs type.\n");
goto finish;
}
/* Ok, we can export it */;
if (!inode->i_sb->s_export_op->find_exported_dentry)
inode->i_sb->s_export_op->find_exported_dentry =
find_exported_dentry;
err = check_export(inode, nxp->ex_flags);
if (err) goto finish;
err = -ENOMEM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment