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