Commit 92ca434d authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] (6/14) resync

do_getattr() renamed to vfs_getattr(), exported and used by
loop.c and nfsd - both blindly accessed ->i_dev/->i_ino of
random inodes when they ought to be calling ->getattr() to
get that information.
parent 6343913a
......@@ -826,17 +826,22 @@ static int loop_set_status(struct loop_device *lo, struct loop_info *arg)
static int loop_get_status(struct loop_device *lo, struct loop_info *arg)
{
struct loop_info info;
struct file *file = lo->lo_backing_file;
struct loop_info info;
struct kstat stat;
int error;
if (lo->lo_state != Lo_bound)
return -ENXIO;
if (!arg)
return -EINVAL;
error = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat);
if (error)
return error;
memset(&info, 0, sizeof(info));
info.lo_number = lo->lo_number;
info.lo_device = kdev_t_to_nr(file->f_dentry->d_inode->i_dev);
info.lo_inode = file->f_dentry->d_inode->i_ino;
info.lo_device = stat.dev;
info.lo_inode = stat.ino;
info.lo_rdevice = lo->lo_device->bd_dev;
info.lo_offset = lo->lo_offset;
info.lo_flags = lo->lo_flags;
......
......@@ -160,35 +160,35 @@ decode_sattr3(u32 *p, struct iattr *iap)
static inline u32 *
encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
{
struct inode *inode = fhp->fh_dentry->d_inode;
struct vfsmount *mnt = fhp->fh_export->ex_mnt;
struct dentry *dentry = fhp->fh_dentry;
struct kstat stat;
vfs_getattr(mnt, dentry, &stat);
*p++ = htonl(nfs3_ftypes[(inode->i_mode & S_IFMT) >> 12]);
*p++ = htonl((u32) inode->i_mode);
*p++ = htonl((u32) inode->i_nlink);
*p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid));
*p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid));
if (S_ISLNK(inode->i_mode) && inode->i_size > NFS3_MAXPATHLEN) {
*p++ = htonl(nfs3_ftypes[(stat.mode & S_IFMT) >> 12]);
*p++ = htonl((u32) stat.mode);
*p++ = htonl((u32) stat.nlink);
*p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid));
*p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid));
if (S_ISLNK(stat.mode) && stat.size > NFS3_MAXPATHLEN) {
p = xdr_encode_hyper(p, (u64) NFS3_MAXPATHLEN);
} else {
p = xdr_encode_hyper(p, (u64) inode->i_size);
p = xdr_encode_hyper(p, (u64) stat.size);
}
if (inode->i_blksize == 0 && inode->i_blocks == 0)
/* Minix file system(?) i_size is (hopefully) close enough */
p = xdr_encode_hyper(p, (u64)(inode->i_size +511)& ~511);
else
p = xdr_encode_hyper(p, ((u64)inode->i_blocks) << 9);
*p++ = htonl((u32) major(inode->i_rdev));
*p++ = htonl((u32) minor(inode->i_rdev));
p = xdr_encode_hyper(p, ((u64)stat.blocks) << 9);
*p++ = htonl((u32) MAJOR(stat.rdev));
*p++ = htonl((u32) MINOR(stat.rdev));
if (rqstp->rq_reffh->fh_version == 1
&& rqstp->rq_reffh->fh_fsid_type == 1
&& (fhp->fh_export->ex_flags & NFSEXP_FSID))
p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
else
p = xdr_encode_hyper(p, (u64) kdev_t_to_nr(inode->i_dev));
p = xdr_encode_hyper(p, (u64) inode->i_ino);
p = encode_time3(p, inode->i_atime);
p = encode_time3(p, lease_get_mtime(inode));
p = encode_time3(p, inode->i_ctime);
p = xdr_encode_hyper(p, (u64) stat.dev);
p = xdr_encode_hyper(p, (u64) stat.ino);
p = encode_time3(p, stat.atime);
p = encode_time3(p, lease_get_mtime(dentry->d_inode));
p = encode_time3(p, stat.ctime);
return p;
}
......
......@@ -134,38 +134,43 @@ decode_sattr(u32 *p, struct iattr *iap)
static inline u32 *
encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
{
struct inode *inode = fhp->fh_dentry->d_inode;
int type = (inode->i_mode & S_IFMT);
struct vfsmount *mnt = fhp->fh_export->ex_mnt;
struct dentry *dentry = fhp->fh_dentry;
struct kstat stat;
int type;
vfs_getattr(mnt, dentry, &stat);
type = (stat.mode & S_IFMT);
*p++ = htonl(nfs_ftypes[type >> 12]);
*p++ = htonl((u32) inode->i_mode);
*p++ = htonl((u32) inode->i_nlink);
*p++ = htonl((u32) nfsd_ruid(rqstp, inode->i_uid));
*p++ = htonl((u32) nfsd_rgid(rqstp, inode->i_gid));
*p++ = htonl((u32) stat.mode);
*p++ = htonl((u32) stat.nlink);
*p++ = htonl((u32) nfsd_ruid(rqstp, stat.uid));
*p++ = htonl((u32) nfsd_rgid(rqstp, stat.gid));
if (S_ISLNK(type) && inode->i_size > NFS_MAXPATHLEN) {
if (S_ISLNK(type) && stat.size > NFS_MAXPATHLEN) {
*p++ = htonl(NFS_MAXPATHLEN);
} else {
*p++ = htonl((u32) inode->i_size);
*p++ = htonl((u32) stat.size);
}
*p++ = htonl((u32) inode->i_blksize);
*p++ = htonl((u32) stat.blksize);
if (S_ISCHR(type) || S_ISBLK(type))
*p++ = htonl((u32) kdev_t_to_nr(inode->i_rdev));
*p++ = htonl((u32) stat.rdev);
else
*p++ = htonl(0xffffffff);
*p++ = htonl((u32) inode->i_blocks);
*p++ = htonl((u32) stat.blocks);
if (rqstp->rq_reffh->fh_version == 1
&& rqstp->rq_reffh->fh_fsid_type == 1
&& (fhp->fh_export->ex_flags & NFSEXP_FSID))
*p++ = htonl((u32) fhp->fh_export->ex_fsid);
else
*p++ = htonl((u32) kdev_t_to_nr(inode->i_dev));
*p++ = htonl((u32) inode->i_ino);
*p++ = htonl((u32) inode->i_atime);
*p++ = htonl((u32) stat.dev);
*p++ = htonl((u32) stat.ino);
*p++ = htonl((u32) stat.atime);
*p++ = 0;
*p++ = htonl((u32) lease_get_mtime(inode));
*p++ = htonl((u32) lease_get_mtime(dentry->d_inode));
*p++ = 0;
*p++ = htonl((u32) inode->i_ctime);
*p++ = htonl((u32) stat.ctime);
*p++ = 0;
return p;
......
......@@ -33,7 +33,7 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
stat->blksize = inode->i_blksize;
}
static int do_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
......@@ -58,7 +58,7 @@ int vfs_stat(char *name, struct kstat *stat)
error = user_path_walk(name, &nd);
if (!error) {
error = do_getattr(nd.mnt, nd.dentry, stat);
error = vfs_getattr(nd.mnt, nd.dentry, stat);
path_release(&nd);
}
return error;
......@@ -71,7 +71,7 @@ int vfs_lstat(char *name, struct kstat *stat)
error = user_path_walk_link(name, &nd);
if (!error) {
error = do_getattr(nd.mnt, nd.dentry, stat);
error = vfs_getattr(nd.mnt, nd.dentry, stat);
path_release(&nd);
}
return error;
......@@ -83,7 +83,7 @@ int vfs_fstat(unsigned int fd, struct kstat *stat)
int error = -EBADF;
if (f) {
error = do_getattr(f->f_vfsmnt, f->f_dentry, stat);
error = vfs_getattr(f->f_vfsmnt, f->f_dentry, stat);
fput(f);
}
return error;
......
......@@ -1246,6 +1246,7 @@ extern int page_follow_link(struct dentry *, struct nameidata *);
extern int page_symlink(struct inode *inode, const char *symname, int len);
extern struct inode_operations page_symlink_inode_operations;
extern void generic_fillattr(struct inode *, struct kstat *);
extern int vfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int vfs_readdir(struct file *, filldir_t, void *);
......
......@@ -256,6 +256,7 @@ EXPORT_SYMBOL(vfs_statfs);
EXPORT_SYMBOL(vfs_fstat);
EXPORT_SYMBOL(vfs_stat);
EXPORT_SYMBOL(vfs_lstat);
EXPORT_SYMBOL(vfs_getattr);
EXPORT_SYMBOL(lock_rename);
EXPORT_SYMBOL(unlock_rename);
EXPORT_SYMBOL(generic_read_dir);
......
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