Skip to content

Commit

Permalink
NFS: Store the file system "fsid" value in the NFS super block.
Browse files Browse the repository at this point in the history
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: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Jun 9, 2006
1 parent 8b512d9 commit 8b4bdcf
Show file tree
Hide file tree
Showing 9 changed files with 30 additions and 15 deletions.
1 change: 0 additions & 1 deletion fs/nfs/idmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
#include <linux/workqueue.h>
#include <linux/sunrpc/rpc_pipe_fs.h>

#include <linux/nfs_fs_sb.h>
#include <linux/nfs_fs.h>

#include <linux/nfs_idmap.h>
Expand Down
8 changes: 8 additions & 0 deletions fs/nfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *f
return ERR_PTR(error);
}

server->fsid = fsinfo->fattr->fsid;
return nfs_fhget(sb, rootfh, fsinfo->fattr);
}

Expand Down Expand Up @@ -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)
{
struct nfs_server *server;
struct nfs_inode *nfsi = NFS_I(inode);
loff_t cur_isize, new_isize;
unsigned int invalid = 0;
Expand All @@ -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))
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.
*/
Expand Down
3 changes: 2 additions & 1 deletion fs/nfs/nfs2xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
fattr->du.nfs2.blocksize = ntohl(*p++);
rdev = 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++);
p = xdr_decode_time(p, &fattr->atime);
p = xdr_decode_time(p, &fattr->mtime);
Expand Down
3 changes: 2 additions & 1 deletion fs/nfs/nfs3xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ xdr_decode_fattr(u32 *p, struct nfs_fattr *fattr)
if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor)
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_time3(p, &fattr->atime);
p = xdr_decode_time3(p, &fattr->mtime);
Expand Down
4 changes: 2 additions & 2 deletions fs/nfs/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2217,7 +2217,7 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap,
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;

Expand Down Expand Up @@ -2863,7 +2863,7 @@ static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, cons
goto xdr_error;
if ((status = decode_attr_size(xdr, bitmap, &fattr->size)) != 0)
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;
if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0)
goto xdr_error;
Expand Down
5 changes: 3 additions & 2 deletions include/linux/nfs_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
#include <linux/rwsem.h>
#include <linux/wait.h>

#include <linux/nfs_fs_sb.h>

#include <linux/sunrpc/debug.h>
#include <linux/sunrpc/auth.h>
#include <linux/sunrpc/clnt.h>
Expand All @@ -27,6 +25,9 @@
#include <linux/nfs3.h>
#include <linux/nfs4.h>
#include <linux/nfs_xdr.h>

#include <linux/nfs_fs_sb.h>

#include <linux/rwsem.h>
#include <linux/mempool.h>

Expand Down
1 change: 1 addition & 0 deletions include/linux/nfs_fs_sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct nfs_server {
char * hostname; /* remote hostname */
struct nfs_fh fh;
struct sockaddr_in addr;
struct nfs_fsid fsid;
unsigned long mount_time; /* when this fs was mounted */
#ifdef CONFIG_NFS_V4
/* Our own IP address, as a null-terminated string.
Expand Down
1 change: 0 additions & 1 deletion include/linux/nfs_page.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include <linux/list.h>
#include <linux/pagemap.h>
#include <linux/wait.h>
#include <linux/nfs_fs_sb.h>
#include <linux/sunrpc/auth.h>
#include <linux/nfs_xdr.h>

Expand Down
19 changes: 12 additions & 7 deletions include/linux/nfs_xdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@
#define NFS_DEF_FILE_IO_SIZE (4096U)
#define NFS_MIN_FILE_IO_SIZE (1024U)

struct nfs4_fsid {
__u64 major;
__u64 minor;
struct nfs_fsid {
uint64_t major;
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 {
unsigned short valid; /* which fields are valid */
__u64 pre_size; /* pre_op_attr.size */
Expand All @@ -40,10 +48,7 @@ struct nfs_fattr {
} nfs3;
} du;
dev_t rdev;
union {
__u64 nfs3; /* also nfs2 */
struct nfs4_fsid nfs4;
} fsid_u;
struct nfs_fsid fsid;
__u64 fileid;
struct timespec atime;
struct timespec mtime;
Expand Down

0 comments on commit 8b4bdcf

Please sign in to comment.