Commit 8b4bdcf8 authored by Trond Myklebust's avatar Trond Myklebust

NFS: Store the file system "fsid" value in the NFS super block.

This should enable us to detect if we are crossing a mountpoint in the
case where the server is exporting "nohide" mounts.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 8b512d9a
...@@ -47,7 +47,6 @@ ...@@ -47,7 +47,6 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/sunrpc/rpc_pipe_fs.h> #include <linux/sunrpc/rpc_pipe_fs.h>
#include <linux/nfs_fs_sb.h>
#include <linux/nfs_fs.h> #include <linux/nfs_fs.h>
#include <linux/nfs_idmap.h> #include <linux/nfs_idmap.h>
......
...@@ -236,6 +236,7 @@ nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *f ...@@ -236,6 +236,7 @@ nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *f
return ERR_PTR(error); return ERR_PTR(error);
} }
server->fsid = fsinfo->fattr->fsid;
return nfs_fhget(sb, rootfh, fsinfo->fattr); return nfs_fhget(sb, rootfh, fsinfo->fattr);
} }
...@@ -1493,6 +1494,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -1493,6 +1494,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
*/ */
static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
{ {
struct nfs_server *server;
struct nfs_inode *nfsi = NFS_I(inode); struct nfs_inode *nfsi = NFS_I(inode);
loff_t cur_isize, new_isize; loff_t cur_isize, new_isize;
unsigned int invalid = 0; unsigned int invalid = 0;
...@@ -1511,6 +1513,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) ...@@ -1511,6 +1513,12 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
goto out_changed; goto out_changed;
server = NFS_SERVER(inode);
/* Update the fsid if and only if this is the root directory */
if (inode == inode->i_sb->s_root->d_inode
&& !nfs_fsid_equal(&server->fsid, &fattr->fsid))
server->fsid = fattr->fsid;
/* /*
* Update the read time so we don't revalidate too often. * Update the read time so we don't revalidate too often.
*/ */
......
...@@ -131,7 +131,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) ...@@ -131,7 +131,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
fattr->du.nfs2.blocksize = ntohl(*p++); fattr->du.nfs2.blocksize = ntohl(*p++);
rdev = ntohl(*p++); rdev = ntohl(*p++);
fattr->du.nfs2.blocks = ntohl(*p++); fattr->du.nfs2.blocks = ntohl(*p++);
fattr->fsid_u.nfs3 = ntohl(*p++); fattr->fsid.major = ntohl(*p++);
fattr->fsid.minor = 0;
fattr->fileid = ntohl(*p++); fattr->fileid = ntohl(*p++);
p = xdr_decode_time(p, &fattr->atime); p = xdr_decode_time(p, &fattr->atime);
p = xdr_decode_time(p, &fattr->mtime); p = xdr_decode_time(p, &fattr->mtime);
......
...@@ -166,7 +166,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr) ...@@ -166,7 +166,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor) if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
fattr->rdev = 0; fattr->rdev = 0;
p = xdr_decode_hyper(p, &fattr->fsid_u.nfs3); p = xdr_decode_hyper(p, &fattr->fsid.major);
fattr->fsid.minor = 0;
p = xdr_decode_hyper(p, &fattr->fileid); p = xdr_decode_hyper(p, &fattr->fileid);
p = xdr_decode_time3(p, &fattr->atime); p = xdr_decode_time3(p, &fattr->atime);
p = xdr_decode_time3(p, &fattr->mtime); p = xdr_decode_time3(p, &fattr->mtime);
......
...@@ -2217,7 +2217,7 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, ...@@ -2217,7 +2217,7 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap,
return 0; return 0;
} }
static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fsid *fsid) static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid)
{ {
uint32_t *p; uint32_t *p;
...@@ -2863,7 +2863,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons ...@@ -2863,7 +2863,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
goto xdr_error; goto xdr_error;
if ((status = decode_attr_size(xdr, bitmap, &fattr->size)) != 0) if ((status = decode_attr_size(xdr, bitmap, &fattr->size)) != 0)
goto xdr_error; goto xdr_error;
if ((status = decode_attr_fsid(xdr, bitmap, &fattr->fsid_u.nfs4)) != 0) if ((status = decode_attr_fsid(xdr, bitmap, &fattr->fsid)) != 0)
goto xdr_error; goto xdr_error;
if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0) if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0)
goto xdr_error; goto xdr_error;
......
...@@ -16,8 +16,6 @@ ...@@ -16,8 +16,6 @@
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/nfs_fs_sb.h>
#include <linux/sunrpc/debug.h> #include <linux/sunrpc/debug.h>
#include <linux/sunrpc/auth.h> #include <linux/sunrpc/auth.h>
#include <linux/sunrpc/clnt.h> #include <linux/sunrpc/clnt.h>
...@@ -27,6 +25,9 @@ ...@@ -27,6 +25,9 @@
#include <linux/nfs3.h> #include <linux/nfs3.h>
#include <linux/nfs4.h> #include <linux/nfs4.h>
#include <linux/nfs_xdr.h> #include <linux/nfs_xdr.h>
#include <linux/nfs_fs_sb.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/mempool.h> #include <linux/mempool.h>
......
...@@ -35,6 +35,7 @@ struct nfs_server { ...@@ -35,6 +35,7 @@ struct nfs_server {
char * hostname; /* remote hostname */ char * hostname; /* remote hostname */
struct nfs_fh fh; struct nfs_fh fh;
struct sockaddr_in addr; struct sockaddr_in addr;
struct nfs_fsid fsid;
unsigned long mount_time; /* when this fs was mounted */ unsigned long mount_time; /* when this fs was mounted */
#ifdef CONFIG_NFS_V4 #ifdef CONFIG_NFS_V4
/* Our own IP address, as a null-terminated string. /* Our own IP address, as a null-terminated string.
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/nfs_fs_sb.h>
#include <linux/sunrpc/auth.h> #include <linux/sunrpc/auth.h>
#include <linux/nfs_xdr.h> #include <linux/nfs_xdr.h>
......
...@@ -14,11 +14,19 @@ ...@@ -14,11 +14,19 @@
#define NFS_DEF_FILE_IO_SIZE (4096U) #define NFS_DEF_FILE_IO_SIZE (4096U)
#define NFS_MIN_FILE_IO_SIZE (1024U) #define NFS_MIN_FILE_IO_SIZE (1024U)
struct nfs4_fsid { struct nfs_fsid {
__u64 major; uint64_t major;
__u64 minor; uint64_t minor;
}; };
/*
* Helper for checking equality between 2 fsids.
*/
static inline int nfs_fsid_equal(const struct nfs_fsid *a, const struct nfs_fsid *b)
{
return a->major == b->major && a->minor == b->minor;
}
struct nfs_fattr { struct nfs_fattr {
unsigned short valid; /* which fields are valid */ unsigned short valid; /* which fields are valid */
__u64 pre_size; /* pre_op_attr.size */ __u64 pre_size; /* pre_op_attr.size */
...@@ -40,10 +48,7 @@ struct nfs_fattr { ...@@ -40,10 +48,7 @@ struct nfs_fattr {
} nfs3; } nfs3;
} du; } du;
dev_t rdev; dev_t rdev;
union { struct nfs_fsid fsid;
__u64 nfs3; /* also nfs2 */
struct nfs4_fsid nfs4;
} fsid_u;
__u64 fileid; __u64 fileid;
struct timespec atime; struct timespec atime;
struct timespec mtime; struct timespec mtime;
......
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