mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 00:21:17 +00:00
[PATCH] knfsd: add some new fsid types
Add support for using a filesystem UUID to identify and export point in the filehandle. For NFSv2, this UUID is xor-ed down to 4 or 8 bytes so that it doesn't take up too much room. For NFSv3+, we use the full 16 bytes, and possibly also a 64bit inode number for exports beneath the root of a filesystem. When generating an fsid to return in 'stat' information, use the UUID (hashed down to size) if it is available and a small 'fsid' was not specifically provided. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
982aedfd09
commit
af6a4e280e
8 changed files with 242 additions and 130 deletions
|
@ -74,19 +74,20 @@ struct svc_export {
|
|||
uid_t ex_anon_uid;
|
||||
gid_t ex_anon_gid;
|
||||
int ex_fsid;
|
||||
unsigned char * ex_uuid; /* 16 byte fsid */
|
||||
struct nfsd4_fs_locations ex_fslocs;
|
||||
};
|
||||
|
||||
/* an "export key" (expkey) maps a filehandlefragement to an
|
||||
* svc_export for a given client. There can be two per export, one
|
||||
* for type 0 (dev/ino), one for type 1 (fsid)
|
||||
* svc_export for a given client. There can be several per export,
|
||||
* for the different fsid types.
|
||||
*/
|
||||
struct svc_expkey {
|
||||
struct cache_head h;
|
||||
|
||||
struct auth_domain * ek_client;
|
||||
int ek_fsidtype;
|
||||
u32 ek_fsid[3];
|
||||
u32 ek_fsid[6];
|
||||
|
||||
struct vfsmount * ek_mnt;
|
||||
struct dentry * ek_dentry;
|
||||
|
|
|
@ -254,18 +254,6 @@ void nfsd_lockd_shutdown(void);
|
|||
*/
|
||||
extern struct timeval nfssvc_boot;
|
||||
|
||||
static inline int is_fsid(struct svc_fh *fh, struct knfsd_fh *reffh)
|
||||
{
|
||||
if (fh->fh_export->ex_flags & NFSEXP_FSID) {
|
||||
struct vfsmount *mnt = fh->fh_export->ex_mnt;
|
||||
if (!old_valid_dev(mnt->mnt_sb->s_dev) ||
|
||||
(reffh->fh_version == 1 && reffh->fh_fsid_type == 1))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_NFSD_V4
|
||||
|
||||
/* before processing a COMPOUND operation, we have to check that there
|
||||
|
|
|
@ -165,38 +165,91 @@ typedef struct svc_fh {
|
|||
|
||||
} svc_fh;
|
||||
|
||||
static inline void mk_fsid_v0(u32 *fsidv, dev_t dev, ino_t ino)
|
||||
{
|
||||
fsidv[0] = htonl((MAJOR(dev)<<16) |
|
||||
MINOR(dev));
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
}
|
||||
enum nfsd_fsid {
|
||||
FSID_DEV = 0,
|
||||
FSID_NUM,
|
||||
FSID_MAJOR_MINOR,
|
||||
FSID_ENCODE_DEV,
|
||||
FSID_UUID4_INUM,
|
||||
FSID_UUID8,
|
||||
FSID_UUID16,
|
||||
FSID_UUID16_INUM,
|
||||
};
|
||||
|
||||
static inline void mk_fsid_v1(u32 *fsidv, u32 fsid)
|
||||
{
|
||||
fsidv[0] = fsid;
|
||||
}
|
||||
enum fsid_source {
|
||||
FSIDSOURCE_DEV,
|
||||
FSIDSOURCE_FSID,
|
||||
FSIDSOURCE_UUID,
|
||||
};
|
||||
extern enum fsid_source fsid_source(struct svc_fh *fhp);
|
||||
|
||||
static inline void mk_fsid_v2(u32 *fsidv, dev_t dev, ino_t ino)
|
||||
{
|
||||
fsidv[0] = htonl(MAJOR(dev));
|
||||
fsidv[1] = htonl(MINOR(dev));
|
||||
fsidv[2] = ino_t_to_u32(ino);
|
||||
}
|
||||
|
||||
static inline void mk_fsid_v3(u32 *fsidv, dev_t dev, ino_t ino)
|
||||
/* This might look a little large to "inline" but in all calls except
|
||||
* one, 'vers' is constant so moste of the function disappears.
|
||||
*/
|
||||
static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino,
|
||||
u32 fsid, unsigned char *uuid)
|
||||
{
|
||||
fsidv[0] = new_encode_dev(dev);
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
u32 *up;
|
||||
switch(vers) {
|
||||
case FSID_DEV:
|
||||
fsidv[0] = htonl((MAJOR(dev)<<16) |
|
||||
MINOR(dev));
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
break;
|
||||
case FSID_NUM:
|
||||
fsidv[0] = fsid;
|
||||
break;
|
||||
case FSID_MAJOR_MINOR:
|
||||
fsidv[0] = htonl(MAJOR(dev));
|
||||
fsidv[1] = htonl(MINOR(dev));
|
||||
fsidv[2] = ino_t_to_u32(ino);
|
||||
break;
|
||||
|
||||
case FSID_ENCODE_DEV:
|
||||
fsidv[0] = new_encode_dev(dev);
|
||||
fsidv[1] = ino_t_to_u32(ino);
|
||||
break;
|
||||
|
||||
case FSID_UUID4_INUM:
|
||||
/* 4 byte fsid and inode number */
|
||||
up = (u32*)uuid;
|
||||
fsidv[0] = ino_t_to_u32(ino);
|
||||
fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3];
|
||||
break;
|
||||
|
||||
case FSID_UUID8:
|
||||
/* 8 byte fsid */
|
||||
up = (u32*)uuid;
|
||||
fsidv[0] = up[0] ^ up[2];
|
||||
fsidv[1] = up[1] ^ up[3];
|
||||
break;
|
||||
|
||||
case FSID_UUID16:
|
||||
/* 16 byte fsid - NFSv3+ only */
|
||||
memcpy(fsidv, uuid, 16);
|
||||
break;
|
||||
|
||||
case FSID_UUID16_INUM:
|
||||
/* 8 byte inode and 16 byte fsid */
|
||||
*(u64*)fsidv = (u64)ino;
|
||||
memcpy(fsidv+2, uuid, 16);
|
||||
break;
|
||||
default: BUG();
|
||||
}
|
||||
}
|
||||
|
||||
static inline int key_len(int type)
|
||||
{
|
||||
switch(type) {
|
||||
case 0: return 8;
|
||||
case 1: return 4;
|
||||
case 2: return 12;
|
||||
case 3: return 8;
|
||||
case FSID_DEV: return 8;
|
||||
case FSID_NUM: return 4;
|
||||
case FSID_MAJOR_MINOR: return 12;
|
||||
case FSID_ENCODE_DEV: return 8;
|
||||
case FSID_UUID4_INUM: return 8;
|
||||
case FSID_UUID8: return 8;
|
||||
case FSID_UUID16: return 16;
|
||||
case FSID_UUID16_INUM: return 24;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue