aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/kernel/osf_sys.c8
-rw-r--r--arch/ia64/ia32/sys_ia32.c23
-rw-r--r--arch/mips/kernel/linux32.c2
-rw-r--r--arch/mips/kernel/sysirix.c10
-rw-r--r--arch/parisc/hpux/fs.c6
-rw-r--r--arch/parisc/kernel/sys_parisc32.c19
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c15
-rw-r--r--arch/s390/kernel/compat_linux.c5
-rw-r--r--arch/sparc/kernel/sys_sunos.c16
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c5
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c12
-rw-r--r--arch/sparc64/solaris/fs.c7
-rw-r--r--arch/x86_64/ia32/sys_ia32.c7
-rw-r--r--fs/afs/dir.c4
-rw-r--r--fs/compat.c18
-rw-r--r--fs/exportfs/expfs.c2
-rw-r--r--fs/fat/dir.c2
-rw-r--r--fs/nfsd/nfs4recover.c2
-rw-r--r--fs/readdir.c18
-rw-r--r--fs/reiserfs/xattr.c6
-rw-r--r--fs/stat.c6
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/stat.h2
23 files changed, 152 insertions, 45 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 8a31fc1bfb15..ad6173651995 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -111,22 +111,26 @@ struct osf_dirent_callback {
111 111
112static int 112static int
113osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, 113osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
114 ino_t ino, unsigned int d_type) 114 u64 ino, unsigned int d_type)
115{ 115{
116 struct osf_dirent __user *dirent; 116 struct osf_dirent __user *dirent;
117 struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; 117 struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf;
118 unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1); 118 unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1);
119 unsigned int d_ino;
119 120
120 buf->error = -EINVAL; /* only used if we fail */ 121 buf->error = -EINVAL; /* only used if we fail */
121 if (reclen > buf->count) 122 if (reclen > buf->count)
122 return -EINVAL; 123 return -EINVAL;
124 d_ino = ino;
125 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
126 return -EOVERFLOW;
123 if (buf->basep) { 127 if (buf->basep) {
124 if (put_user(offset, buf->basep)) 128 if (put_user(offset, buf->basep))
125 return -EFAULT; 129 return -EFAULT;
126 buf->basep = NULL; 130 buf->basep = NULL;
127 } 131 }
128 dirent = buf->dirent; 132 dirent = buf->dirent;
129 put_user(ino, &dirent->d_ino); 133 put_user(d_ino, &dirent->d_ino);
130 put_user(namlen, &dirent->d_namlen); 134 put_user(namlen, &dirent->d_namlen);
131 put_user(reclen, &dirent->d_reclen); 135 put_user(reclen, &dirent->d_reclen);
132 if (copy_to_user(dirent->d_name, name, namlen) || 136 if (copy_to_user(dirent->d_name, name, namlen) ||
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index bddbd22706ed..9d6a3f210148 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -125,6 +125,7 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use
125 125
126int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) 126int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
127{ 127{
128 compat_ino_t ino;
128 int err; 129 int err;
129 130
130 if ((u64) stat->size > MAX_NON_LFS || 131 if ((u64) stat->size > MAX_NON_LFS ||
@@ -132,11 +133,15 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
132 !old_valid_dev(stat->rdev)) 133 !old_valid_dev(stat->rdev))
133 return -EOVERFLOW; 134 return -EOVERFLOW;
134 135
136 ino = stat->ino;
137 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
138 return -EOVERFLOW;
139
135 if (clear_user(ubuf, sizeof(*ubuf))) 140 if (clear_user(ubuf, sizeof(*ubuf)))
136 return -EFAULT; 141 return -EFAULT;
137 142
138 err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); 143 err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
139 err |= __put_user(stat->ino, &ubuf->st_ino); 144 err |= __put_user(ino, &ubuf->st_ino);
140 err |= __put_user(stat->mode, &ubuf->st_mode); 145 err |= __put_user(stat->mode, &ubuf->st_mode);
141 err |= __put_user(stat->nlink, &ubuf->st_nlink); 146 err |= __put_user(stat->nlink, &ubuf->st_nlink);
142 err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); 147 err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
@@ -1222,16 +1227,20 @@ struct readdir32_callback {
1222}; 1227};
1223 1228
1224static int 1229static int
1225filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, 1230filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino,
1226 unsigned int d_type) 1231 unsigned int d_type)
1227{ 1232{
1228 struct compat_dirent __user * dirent; 1233 struct compat_dirent __user * dirent;
1229 struct getdents32_callback * buf = (struct getdents32_callback *) __buf; 1234 struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
1230 int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4); 1235 int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4);
1236 u32 d_ino;
1231 1237
1232 buf->error = -EINVAL; /* only used if we fail.. */ 1238 buf->error = -EINVAL; /* only used if we fail.. */
1233 if (reclen > buf->count) 1239 if (reclen > buf->count)
1234 return -EINVAL; 1240 return -EINVAL;
1241 d_ino = ino;
1242 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
1243 return -EOVERFLOW;
1235 buf->error = -EFAULT; /* only used if we fail.. */ 1244 buf->error = -EFAULT; /* only used if we fail.. */
1236 dirent = buf->previous; 1245 dirent = buf->previous;
1237 if (dirent) 1246 if (dirent)
@@ -1239,7 +1248,7 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
1239 return -EFAULT; 1248 return -EFAULT;
1240 dirent = buf->current_dir; 1249 dirent = buf->current_dir;
1241 buf->previous = dirent; 1250 buf->previous = dirent;
1242 if (put_user(ino, &dirent->d_ino) 1251 if (put_user(d_ino, &dirent->d_ino)
1243 || put_user(reclen, &dirent->d_reclen) 1252 || put_user(reclen, &dirent->d_reclen)
1244 || copy_to_user(dirent->d_name, name, namlen) 1253 || copy_to_user(dirent->d_name, name, namlen)
1245 || put_user(0, dirent->d_name + namlen)) 1254 || put_user(0, dirent->d_name + namlen))
@@ -1287,17 +1296,21 @@ out:
1287} 1296}
1288 1297
1289static int 1298static int
1290fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, 1299fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino,
1291 unsigned int d_type) 1300 unsigned int d_type)
1292{ 1301{
1293 struct readdir32_callback * buf = (struct readdir32_callback *) __buf; 1302 struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
1294 struct old_linux32_dirent __user * dirent; 1303 struct old_linux32_dirent __user * dirent;
1304 u32 d_ino;
1295 1305
1296 if (buf->count) 1306 if (buf->count)
1297 return -EINVAL; 1307 return -EINVAL;
1308 d_ino = ino;
1309 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
1310 return -EOVERFLOW;
1298 buf->count++; 1311 buf->count++;
1299 dirent = buf->dirent; 1312 dirent = buf->dirent;
1300 if (put_user(ino, &dirent->d_ino) 1313 if (put_user(d_ino, &dirent->d_ino)
1301 || put_user(offset, &dirent->d_offset) 1314 || put_user(offset, &dirent->d_offset)
1302 || put_user(namlen, &dirent->d_namlen) 1315 || put_user(namlen, &dirent->d_namlen)
1303 || copy_to_user(dirent->d_name, name, namlen) 1316 || copy_to_user(dirent->d_name, name, namlen)
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 52cada45b353..53f4171fc188 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -77,6 +77,8 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
77 memset(&tmp, 0, sizeof(tmp)); 77 memset(&tmp, 0, sizeof(tmp));
78 tmp.st_dev = new_encode_dev(stat->dev); 78 tmp.st_dev = new_encode_dev(stat->dev);
79 tmp.st_ino = stat->ino; 79 tmp.st_ino = stat->ino;
80 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
81 return -EOVERFLOW;
80 tmp.st_mode = stat->mode; 82 tmp.st_mode = stat->mode;
81 tmp.st_nlink = stat->nlink; 83 tmp.st_nlink = stat->nlink;
82 SET_UID(tmp.st_uid, stat->uid); 84 SET_UID(tmp.st_uid, stat->uid);
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 11bb97174972..93c74fefff76 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -1739,12 +1739,13 @@ struct irix_dirent32_callback {
1739#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) 1739#define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1))
1740 1740
1741static int irix_filldir32(void *__buf, const char *name, 1741static int irix_filldir32(void *__buf, const char *name,
1742 int namlen, loff_t offset, ino_t ino, unsigned int d_type) 1742 int namlen, loff_t offset, u64 ino, unsigned int d_type)
1743{ 1743{
1744 struct irix_dirent32 __user *dirent; 1744 struct irix_dirent32 __user *dirent;
1745 struct irix_dirent32_callback *buf = __buf; 1745 struct irix_dirent32_callback *buf = __buf;
1746 unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1); 1746 unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
1747 int err = 0; 1747 int err = 0;
1748 u32 d_ino;
1748 1749
1749#ifdef DEBUG_GETDENTS 1750#ifdef DEBUG_GETDENTS
1750 printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", 1751 printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
@@ -1753,12 +1754,15 @@ static int irix_filldir32(void *__buf, const char *name,
1753 buf->error = -EINVAL; /* only used if we fail.. */ 1754 buf->error = -EINVAL; /* only used if we fail.. */
1754 if (reclen > buf->count) 1755 if (reclen > buf->count)
1755 return -EINVAL; 1756 return -EINVAL;
1757 d_ino = ino;
1758 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
1759 return -EOVERFLOW;
1756 dirent = buf->previous; 1760 dirent = buf->previous;
1757 if (dirent) 1761 if (dirent)
1758 err = __put_user(offset, &dirent->d_off); 1762 err = __put_user(offset, &dirent->d_off);
1759 dirent = buf->current_dir; 1763 dirent = buf->current_dir;
1760 err |= __put_user(dirent, &buf->previous); 1764 err |= __put_user(dirent, &buf->previous);
1761 err |= __put_user(ino, &dirent->d_ino); 1765 err |= __put_user(d_ino, &dirent->d_ino);
1762 err |= __put_user(reclen, &dirent->d_reclen); 1766 err |= __put_user(reclen, &dirent->d_reclen);
1763 err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0; 1767 err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0;
1764 err |= __put_user(0, &dirent->d_name[namlen]); 1768 err |= __put_user(0, &dirent->d_name[namlen]);
@@ -1837,7 +1841,7 @@ struct irix_dirent64_callback {
1837#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) 1841#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))
1838 1842
1839static int irix_filldir64(void *__buf, const char *name, 1843static int irix_filldir64(void *__buf, const char *name,
1840 int namlen, loff_t offset, ino_t ino, unsigned int d_type) 1844 int namlen, loff_t offset, u64 ino, unsigned int d_type)
1841{ 1845{
1842 struct irix_dirent64 __user *dirent; 1846 struct irix_dirent64 __user *dirent;
1843 struct irix_dirent64_callback * buf = __buf; 1847 struct irix_dirent64_callback * buf = __buf;
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c
index d7c80edf4489..6e79dbf3f6bd 100644
--- a/arch/parisc/hpux/fs.c
+++ b/arch/parisc/hpux/fs.c
@@ -77,17 +77,21 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
77{ 77{
78 struct hpux_dirent * dirent; 78 struct hpux_dirent * dirent;
79 struct getdents_callback * buf = (struct getdents_callback *) __buf; 79 struct getdents_callback * buf = (struct getdents_callback *) __buf;
80 ino_t d_ino;
80 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); 81 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
81 82
82 buf->error = -EINVAL; /* only used if we fail.. */ 83 buf->error = -EINVAL; /* only used if we fail.. */
83 if (reclen > buf->count) 84 if (reclen > buf->count)
84 return -EINVAL; 85 return -EINVAL;
86 d_ino = ino;
87 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
88 return -EOVERFLOW;
85 dirent = buf->previous; 89 dirent = buf->previous;
86 if (dirent) 90 if (dirent)
87 put_user(offset, &dirent->d_off); 91 put_user(offset, &dirent->d_off);
88 dirent = buf->current_dir; 92 dirent = buf->current_dir;
89 buf->previous = dirent; 93 buf->previous = dirent;
90 put_user(ino, &dirent->d_ino); 94 put_user(d_ino, &dirent->d_ino);
91 put_user(reclen, &dirent->d_reclen); 95 put_user(reclen, &dirent->d_reclen);
92 put_user(namlen, &dirent->d_namlen); 96 put_user(namlen, &dirent->d_namlen);
93 copy_to_user(dirent->d_name, name, namlen); 97 copy_to_user(dirent->d_name, name, namlen);
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index b74869803081..e3b30bc36453 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -237,14 +237,19 @@ int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user
237 237
238int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) 238int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
239{ 239{
240 compat_ino_t ino;
240 int err; 241 int err;
241 242
242 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || 243 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
243 !new_valid_dev(stat->rdev)) 244 !new_valid_dev(stat->rdev))
244 return -EOVERFLOW; 245 return -EOVERFLOW;
245 246
247 ino = stat->ino;
248 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
249 return -EOVERFLOW;
250
246 err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); 251 err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
247 err |= put_user(stat->ino, &statbuf->st_ino); 252 err |= put_user(ino, &statbuf->st_ino);
248 err |= put_user(stat->mode, &statbuf->st_mode); 253 err |= put_user(stat->mode, &statbuf->st_mode);
249 err |= put_user(stat->nlink, &statbuf->st_nlink); 254 err |= put_user(stat->nlink, &statbuf->st_nlink);
250 err |= put_user(0, &statbuf->st_reserved1); 255 err |= put_user(0, &statbuf->st_reserved1);
@@ -312,16 +317,20 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino,
312 struct linux32_dirent __user * dirent; 317 struct linux32_dirent __user * dirent;
313 struct getdents32_callback * buf = (struct getdents32_callback *) __buf; 318 struct getdents32_callback * buf = (struct getdents32_callback *) __buf;
314 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); 319 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4);
320 u32 d_ino;
315 321
316 buf->error = -EINVAL; /* only used if we fail.. */ 322 buf->error = -EINVAL; /* only used if we fail.. */
317 if (reclen > buf->count) 323 if (reclen > buf->count)
318 return -EINVAL; 324 return -EINVAL;
325 d_ino = ino;
326 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
327 return -EOVERFLOW;
319 dirent = buf->previous; 328 dirent = buf->previous;
320 if (dirent) 329 if (dirent)
321 put_user(offset, &dirent->d_off); 330 put_user(offset, &dirent->d_off);
322 dirent = buf->current_dir; 331 dirent = buf->current_dir;
323 buf->previous = dirent; 332 buf->previous = dirent;
324 put_user(ino, &dirent->d_ino); 333 put_user(d_ino, &dirent->d_ino);
325 put_user(reclen, &dirent->d_reclen); 334 put_user(reclen, &dirent->d_reclen);
326 copy_to_user(dirent->d_name, name, namlen); 335 copy_to_user(dirent->d_name, name, namlen);
327 put_user(0, dirent->d_name + namlen); 336 put_user(0, dirent->d_name + namlen);
@@ -371,12 +380,16 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t
371{ 380{
372 struct readdir32_callback * buf = (struct readdir32_callback *) __buf; 381 struct readdir32_callback * buf = (struct readdir32_callback *) __buf;
373 struct old_linux32_dirent __user * dirent; 382 struct old_linux32_dirent __user * dirent;
383 u32 d_ino;
374 384
375 if (buf->count) 385 if (buf->count)
376 return -EINVAL; 386 return -EINVAL;
387 d_ino = ino;
388 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
389 return -EOVERFLOW;
377 buf->count++; 390 buf->count++;
378 dirent = buf->dirent; 391 dirent = buf->dirent;
379 put_user(ino, &dirent->d_ino); 392 put_user(d_ino, &dirent->d_ino);
380 put_user(offset, &dirent->d_offset); 393 put_user(offset, &dirent->d_offset);
381 put_user(namlen, &dirent->d_namlen); 394 put_user(namlen, &dirent->d_namlen);
382 copy_to_user(dirent->d_name, name, namlen); 395 copy_to_user(dirent->d_name, name, namlen);
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index 5e391fc25340..d15c33e95959 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -69,16 +69,20 @@ struct readdir_callback32 {
69}; 69};
70 70
71static int fillonedir(void * __buf, const char * name, int namlen, 71static int fillonedir(void * __buf, const char * name, int namlen,
72 off_t offset, ino_t ino, unsigned int d_type) 72 off_t offset, u64 ino, unsigned int d_type)
73{ 73{
74 struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; 74 struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf;
75 struct old_linux_dirent32 __user * dirent; 75 struct old_linux_dirent32 __user * dirent;
76 ino_t d_ino;
76 77
77 if (buf->count) 78 if (buf->count)
78 return -EINVAL; 79 return -EINVAL;
80 d_ino = ino;
81 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
82 return -EOVERFLOW;
79 buf->count++; 83 buf->count++;
80 dirent = buf->dirent; 84 dirent = buf->dirent;
81 put_user(ino, &dirent->d_ino); 85 put_user(d_ino, &dirent->d_ino);
82 put_user(offset, &dirent->d_offset); 86 put_user(offset, &dirent->d_offset);
83 put_user(namlen, &dirent->d_namlen); 87 put_user(namlen, &dirent->d_namlen);
84 copy_to_user(dirent->d_name, name, namlen); 88 copy_to_user(dirent->d_name, name, namlen);
@@ -120,15 +124,20 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
120 124
121int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) 125int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
122{ 126{
127 compat_ino_t ino;
123 long err; 128 long err;
124 129
125 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || 130 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
126 !new_valid_dev(stat->rdev)) 131 !new_valid_dev(stat->rdev))
127 return -EOVERFLOW; 132 return -EOVERFLOW;
128 133
134 ino = stat->ino;
135 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
136 return -EOVERFLOW;
137
129 err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; 138 err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
130 err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); 139 err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
131 err |= __put_user(stat->ino, &statbuf->st_ino); 140 err |= __put_user(ino, &statbuf->st_ino);
132 err |= __put_user(stat->mode, &statbuf->st_mode); 141 err |= __put_user(stat->mode, &statbuf->st_mode);
133 err |= __put_user(stat->nlink, &statbuf->st_nlink); 142 err |= __put_user(stat->nlink, &statbuf->st_nlink);
134 err |= __put_user(stat->uid, &statbuf->st_uid); 143 err |= __put_user(stat->uid, &statbuf->st_uid);
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index c46e3d48e410..e15e1489aef5 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -357,11 +357,16 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
357 357
358int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) 358int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
359{ 359{
360 compat_ino_t ino;
360 int err; 361 int err;
361 362
362 if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) 363 if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
363 return -EOVERFLOW; 364 return -EOVERFLOW;
364 365
366 ino = stat->ino;
367 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
368 return -EOVERFLOW;
369
365 err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); 370 err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
366 err |= put_user(stat->ino, &statbuf->st_ino); 371 err |= put_user(stat->ino, &statbuf->st_ino);
367 err |= put_user(stat->mode, &statbuf->st_mode); 372 err |= put_user(stat->mode, &statbuf->st_mode);
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index 9d2cd97d1c3a..6f3ac548ee66 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -325,21 +325,25 @@ struct sunos_dirent_callback {
325#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) 325#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
326 326
327static int sunos_filldir(void * __buf, const char * name, int namlen, 327static int sunos_filldir(void * __buf, const char * name, int namlen,
328 loff_t offset, ino_t ino, unsigned int d_type) 328 loff_t offset, u64 ino, unsigned int d_type)
329{ 329{
330 struct sunos_dirent __user *dirent; 330 struct sunos_dirent __user *dirent;
331 struct sunos_dirent_callback * buf = __buf; 331 struct sunos_dirent_callback * buf = __buf;
332 unsigned long d_ino;
332 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); 333 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
333 334
334 buf->error = -EINVAL; /* only used if we fail.. */ 335 buf->error = -EINVAL; /* only used if we fail.. */
335 if (reclen > buf->count) 336 if (reclen > buf->count)
336 return -EINVAL; 337 return -EINVAL;
338 d_ino = ino;
339 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
340 return -EOVERFLOW;
337 dirent = buf->previous; 341 dirent = buf->previous;
338 if (dirent) 342 if (dirent)
339 put_user(offset, &dirent->d_off); 343 put_user(offset, &dirent->d_off);
340 dirent = buf->curr; 344 dirent = buf->curr;
341 buf->previous = dirent; 345 buf->previous = dirent;
342 put_user(ino, &dirent->d_ino); 346 put_user(d_ino, &dirent->d_ino);
343 put_user(namlen, &dirent->d_namlen); 347 put_user(namlen, &dirent->d_namlen);
344 put_user(reclen, &dirent->d_reclen); 348 put_user(reclen, &dirent->d_reclen);
345 copy_to_user(dirent->d_name, name, namlen); 349 copy_to_user(dirent->d_name, name, namlen);
@@ -406,19 +410,23 @@ struct sunos_direntry_callback {
406}; 410};
407 411
408static int sunos_filldirentry(void * __buf, const char * name, int namlen, 412static int sunos_filldirentry(void * __buf, const char * name, int namlen,
409 loff_t offset, ino_t ino, unsigned int d_type) 413 loff_t offset, u64 ino, unsigned int d_type)
410{ 414{
411 struct sunos_direntry __user *dirent; 415 struct sunos_direntry __user *dirent;
412 struct sunos_direntry_callback *buf = __buf; 416 struct sunos_direntry_callback *buf = __buf;
417 unsigned long d_ino;
413 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); 418 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
414 419
415 buf->error = -EINVAL; /* only used if we fail.. */ 420 buf->error = -EINVAL; /* only used if we fail.. */
416 if (reclen > buf->count) 421 if (reclen > buf->count)
417 return -EINVAL; 422 return -EINVAL;
423 d_ino = ino;
424 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
425 return -EOVERFLOW;
418 dirent = buf->previous; 426 dirent = buf->previous;
419 dirent = buf->curr; 427 dirent = buf->curr;
420 buf->previous = dirent; 428 buf->previous = dirent;
421 put_user(ino, &dirent->d_ino); 429 put_user(d_ino, &dirent->d_ino);
422 put_user(namlen, &dirent->d_namlen); 430 put_user(namlen, &dirent->d_namlen);
423 put_user(reclen, &dirent->d_reclen); 431 put_user(reclen, &dirent->d_reclen);
424 copy_to_user(dirent->d_name, name, namlen); 432 copy_to_user(dirent->d_name, name, namlen);
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 69444f266e2d..dbc6d1a3be1f 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -337,12 +337,17 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
337 337
338int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) 338int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
339{ 339{
340 compat_ino_t ino;
340 int err; 341 int err;
341 342
342 if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) || 343 if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
343 !old_valid_dev(stat->rdev)) 344 !old_valid_dev(stat->rdev))
344 return -EOVERFLOW; 345 return -EOVERFLOW;
345 346
347 ino = stat->ino;
348 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
349 return -EOVERFLOW;
350
346 err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); 351 err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
347 err |= put_user(stat->ino, &statbuf->st_ino); 352 err |= put_user(stat->ino, &statbuf->st_ino);
348 err |= put_user(stat->mode, &statbuf->st_mode); 353 err |= put_user(stat->mode, &statbuf->st_mode);
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 953296b73f3f..e414c8ef0225 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -280,16 +280,20 @@ static int sunos_filldir(void * __buf, const char * name, int namlen,
280 struct sunos_dirent __user *dirent; 280 struct sunos_dirent __user *dirent;
281 struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; 281 struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
282 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); 282 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
283 u32 d_ino;
283 284
284 buf->error = -EINVAL; /* only used if we fail.. */ 285 buf->error = -EINVAL; /* only used if we fail.. */
285 if (reclen > buf->count) 286 if (reclen > buf->count)
286 return -EINVAL; 287 return -EINVAL;
288 d_ino = ino;
289 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
290 return -EOVERFLOW;
287 dirent = buf->previous; 291 dirent = buf->previous;
288 if (dirent) 292 if (dirent)
289 put_user(offset, &dirent->d_off); 293 put_user(offset, &dirent->d_off);
290 dirent = buf->curr; 294 dirent = buf->curr;
291 buf->previous = dirent; 295 buf->previous = dirent;
292 put_user(ino, &dirent->d_ino); 296 put_user(d_ino, &dirent->d_ino);
293 put_user(namlen, &dirent->d_namlen); 297 put_user(namlen, &dirent->d_namlen);
294 put_user(reclen, &dirent->d_reclen); 298 put_user(reclen, &dirent->d_reclen);
295 if (copy_to_user(dirent->d_name, name, namlen)) 299 if (copy_to_user(dirent->d_name, name, namlen))
@@ -363,14 +367,18 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen,
363 struct sunos_direntry_callback * buf = 367 struct sunos_direntry_callback * buf =
364 (struct sunos_direntry_callback *) __buf; 368 (struct sunos_direntry_callback *) __buf;
365 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); 369 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
370 u32 d_ino;
366 371
367 buf->error = -EINVAL; /* only used if we fail.. */ 372 buf->error = -EINVAL; /* only used if we fail.. */
368 if (reclen > buf->count) 373 if (reclen > buf->count)
369 return -EINVAL; 374 return -EINVAL;
375 d_ino = ino;
376 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
377 return -EOVERFLOW;
370 dirent = buf->previous; 378 dirent = buf->previous;
371 dirent = buf->curr; 379 dirent = buf->curr;
372 buf->previous = dirent; 380 buf->previous = dirent;
373 put_user(ino, &dirent->d_ino); 381 put_user(d_ino, &dirent->d_ino);
374 put_user(namlen, &dirent->d_namlen); 382 put_user(namlen, &dirent->d_namlen);
375 put_user(reclen, &dirent->d_reclen); 383 put_user(reclen, &dirent->d_reclen);
376 if (copy_to_user(dirent->d_name, name, namlen)) 384 if (copy_to_user(dirent->d_name, name, namlen))
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 0f0eb6aa1c40..12a940cc791f 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -82,12 +82,17 @@ struct sol_stat64 {
82 82
83static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf) 83static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf)
84{ 84{
85 u32 ino;
86
85 if (kbuf->size > MAX_NON_LFS || 87 if (kbuf->size > MAX_NON_LFS ||
86 !sysv_valid_dev(kbuf->dev) || 88 !sysv_valid_dev(kbuf->dev) ||
87 !sysv_valid_dev(kbuf->rdev)) 89 !sysv_valid_dev(kbuf->rdev))
88 return -EOVERFLOW; 90 return -EOVERFLOW;
91 ino = kbuf->ino;
92 if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
93 return -EOVERFLOW;
89 if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) || 94 if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
90 __put_user (kbuf->ino, &ubuf->st_ino) || 95 __put_user (ino, &ubuf->st_ino) ||
91 __put_user (kbuf->mode, &ubuf->st_mode) || 96 __put_user (kbuf->mode, &ubuf->st_mode) ||
92 __put_user (kbuf->nlink, &ubuf->st_nlink) || 97 __put_user (kbuf->nlink, &ubuf->st_nlink) ||
93 __put_user (kbuf->uid, &ubuf->st_uid) || 98 __put_user (kbuf->uid, &ubuf->st_uid) ||
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c
index 26a01717cc1a..c9bac3af29d6 100644
--- a/arch/x86_64/ia32/sys_ia32.c
+++ b/arch/x86_64/ia32/sys_ia32.c
@@ -76,6 +76,8 @@
76 76
77int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) 77int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
78{ 78{
79 compat_ino_t ino;
80
79 typeof(ubuf->st_uid) uid = 0; 81 typeof(ubuf->st_uid) uid = 0;
80 typeof(ubuf->st_gid) gid = 0; 82 typeof(ubuf->st_gid) gid = 0;
81 SET_UID(uid, kbuf->uid); 83 SET_UID(uid, kbuf->uid);
@@ -84,9 +86,12 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
84 return -EOVERFLOW; 86 return -EOVERFLOW;
85 if (kbuf->size >= 0x7fffffff) 87 if (kbuf->size >= 0x7fffffff)
86 return -EOVERFLOW; 88 return -EOVERFLOW;
89 ino = kbuf->ino;
90 if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
91 return -EOVERFLOW;
87 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || 92 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
88 __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) || 93 __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
89 __put_user (kbuf->ino, &ubuf->st_ino) || 94 __put_user (ino, &ubuf->st_ino) ||
90 __put_user (kbuf->mode, &ubuf->st_mode) || 95 __put_user (kbuf->mode, &ubuf->st_mode) ||
91 __put_user (kbuf->nlink, &ubuf->st_nlink) || 96 __put_user (kbuf->nlink, &ubuf->st_nlink) ||
92 __put_user (uid, &ubuf->st_uid) || 97 __put_user (uid, &ubuf->st_uid) ||
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 2fc99877cb0d..cf8a2cb28505 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -30,7 +30,7 @@ static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir);
30static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); 30static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
31static int afs_d_delete(struct dentry *dentry); 31static int afs_d_delete(struct dentry *dentry);
32static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, 32static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
33 loff_t fpos, ino_t ino, unsigned dtype); 33 loff_t fpos, u64 ino, unsigned dtype);
34 34
35const struct file_operations afs_dir_file_operations = { 35const struct file_operations afs_dir_file_operations = {
36 .open = afs_dir_open, 36 .open = afs_dir_open,
@@ -409,7 +409,7 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir)
409 * uniquifier through dtype 409 * uniquifier through dtype
410 */ 410 */
411static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, 411static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
412 loff_t fpos, ino_t ino, unsigned dtype) 412 loff_t fpos, u64 ino, unsigned dtype)
413{ 413{
414 struct afs_dir_lookup_cookie *cookie = _cookie; 414 struct afs_dir_lookup_cookie *cookie = _cookie;
415 415
diff --git a/fs/compat.c b/fs/compat.c
index d98c96f4a44d..4d3fbcb2ddb1 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -914,20 +914,24 @@ struct compat_readdir_callback {
914}; 914};
915 915
916static int compat_fillonedir(void *__buf, const char *name, int namlen, 916static int compat_fillonedir(void *__buf, const char *name, int namlen,
917 loff_t offset, ino_t ino, unsigned int d_type) 917 loff_t offset, u64 ino, unsigned int d_type)
918{ 918{
919 struct compat_readdir_callback *buf = __buf; 919 struct compat_readdir_callback *buf = __buf;
920 struct compat_old_linux_dirent __user *dirent; 920 struct compat_old_linux_dirent __user *dirent;
921 compat_ulong_t d_ino;
921 922
922 if (buf->result) 923 if (buf->result)
923 return -EINVAL; 924 return -EINVAL;
925 d_ino = ino;
926 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
927 return -EOVERFLOW;
924 buf->result++; 928 buf->result++;
925 dirent = buf->dirent; 929 dirent = buf->dirent;
926 if (!access_ok(VERIFY_WRITE, dirent, 930 if (!access_ok(VERIFY_WRITE, dirent,
927 (unsigned long)(dirent->d_name + namlen + 1) - 931 (unsigned long)(dirent->d_name + namlen + 1) -
928 (unsigned long)dirent)) 932 (unsigned long)dirent))
929 goto efault; 933 goto efault;
930 if ( __put_user(ino, &dirent->d_ino) || 934 if ( __put_user(d_ino, &dirent->d_ino) ||
931 __put_user(offset, &dirent->d_offset) || 935 __put_user(offset, &dirent->d_offset) ||
932 __put_user(namlen, &dirent->d_namlen) || 936 __put_user(namlen, &dirent->d_namlen) ||
933 __copy_to_user(dirent->d_name, name, namlen) || 937 __copy_to_user(dirent->d_name, name, namlen) ||
@@ -978,22 +982,26 @@ struct compat_getdents_callback {
978}; 982};
979 983
980static int compat_filldir(void *__buf, const char *name, int namlen, 984static int compat_filldir(void *__buf, const char *name, int namlen,
981 loff_t offset, ino_t ino, unsigned int d_type) 985 loff_t offset, u64 ino, unsigned int d_type)
982{ 986{
983 struct compat_linux_dirent __user * dirent; 987 struct compat_linux_dirent __user * dirent;
984 struct compat_getdents_callback *buf = __buf; 988 struct compat_getdents_callback *buf = __buf;
989 compat_ulong_t d_ino;
985 int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); 990 int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
986 991
987 buf->error = -EINVAL; /* only used if we fail.. */ 992 buf->error = -EINVAL; /* only used if we fail.. */
988 if (reclen > buf->count) 993 if (reclen > buf->count)
989 return -EINVAL; 994 return -EINVAL;
995 d_ino = ino;
996 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
997 return -EOVERFLOW;
990 dirent = buf->previous; 998 dirent = buf->previous;
991 if (dirent) { 999 if (dirent) {
992 if (__put_user(offset, &dirent->d_off)) 1000 if (__put_user(offset, &dirent->d_off))
993 goto efault; 1001 goto efault;
994 } 1002 }
995 dirent = buf->current_dir; 1003 dirent = buf->current_dir;
996 if (__put_user(ino, &dirent->d_ino)) 1004 if (__put_user(d_ino, &dirent->d_ino))
997 goto efault; 1005 goto efault;
998 if (__put_user(reclen, &dirent->d_reclen)) 1006 if (__put_user(reclen, &dirent->d_reclen))
999 goto efault; 1007 goto efault;
@@ -1064,7 +1072,7 @@ struct compat_getdents_callback64 {
1064}; 1072};
1065 1073
1066static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset, 1074static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset,
1067 ino_t ino, unsigned int d_type) 1075 u64 ino, unsigned int d_type)
1068{ 1076{
1069 struct linux_dirent64 __user *dirent; 1077 struct linux_dirent64 __user *dirent;
1070 struct compat_getdents_callback64 *buf = __buf; 1078 struct compat_getdents_callback64 *buf = __buf;
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 4c39009350f3..93e77c3d2490 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -315,7 +315,7 @@ struct getdents_callback {
315 * the name matching the specified inode number. 315 * the name matching the specified inode number.
316 */ 316 */
317static int filldir_one(void * __buf, const char * name, int len, 317static int filldir_one(void * __buf, const char * name, int len,
318 loff_t pos, ino_t ino, unsigned int d_type) 318 loff_t pos, u64 ino, unsigned int d_type)
319{ 319{
320 struct getdents_callback *buf = __buf; 320 struct getdents_callback *buf = __buf;
321 int result = 0; 321 int result = 0;
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index 3e50a4166283..69c439f44387 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -648,7 +648,7 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir)
648} 648}
649 649
650static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, 650static int fat_ioctl_filldir(void *__buf, const char *name, int name_len,
651 loff_t offset, ino_t ino, unsigned int d_type) 651 loff_t offset, u64 ino, unsigned int d_type)
652{ 652{
653 struct fat_ioctl_filldir_callback *buf = __buf; 653 struct fat_ioctl_filldir_callback *buf = __buf;
654 struct dirent __user *d1 = buf->dirent; 654 struct dirent __user *d1 = buf->dirent;
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index e35d7e52fdeb..1cbd2e4ee122 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -184,7 +184,7 @@ struct dentry_list_arg {
184 184
185static int 185static int
186nfsd4_build_dentrylist(void *arg, const char *name, int namlen, 186nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
187 loff_t offset, ino_t ino, unsigned int d_type) 187 loff_t offset, u64 ino, unsigned int d_type)
188{ 188{
189 struct dentry_list_arg *dla = arg; 189 struct dentry_list_arg *dla = arg;
190 struct list_head *dentries = &dla->dentries; 190 struct list_head *dentries = &dla->dentries;
diff --git a/fs/readdir.c b/fs/readdir.c
index b6109329b607..bff3ee58e2f8 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -69,20 +69,24 @@ struct readdir_callback {
69}; 69};
70 70
71static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, 71static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
72 ino_t ino, unsigned int d_type) 72 u64 ino, unsigned int d_type)
73{ 73{
74 struct readdir_callback * buf = (struct readdir_callback *) __buf; 74 struct readdir_callback * buf = (struct readdir_callback *) __buf;
75 struct old_linux_dirent __user * dirent; 75 struct old_linux_dirent __user * dirent;
76 unsigned long d_ino;
76 77
77 if (buf->result) 78 if (buf->result)
78 return -EINVAL; 79 return -EINVAL;
80 d_ino = ino;
81 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
82 return -EOVERFLOW;
79 buf->result++; 83 buf->result++;
80 dirent = buf->dirent; 84 dirent = buf->dirent;
81 if (!access_ok(VERIFY_WRITE, dirent, 85 if (!access_ok(VERIFY_WRITE, dirent,
82 (unsigned long)(dirent->d_name + namlen + 1) - 86 (unsigned long)(dirent->d_name + namlen + 1) -
83 (unsigned long)dirent)) 87 (unsigned long)dirent))
84 goto efault; 88 goto efault;
85 if ( __put_user(ino, &dirent->d_ino) || 89 if ( __put_user(d_ino, &dirent->d_ino) ||
86 __put_user(offset, &dirent->d_offset) || 90 __put_user(offset, &dirent->d_offset) ||
87 __put_user(namlen, &dirent->d_namlen) || 91 __put_user(namlen, &dirent->d_namlen) ||
88 __copy_to_user(dirent->d_name, name, namlen) || 92 __copy_to_user(dirent->d_name, name, namlen) ||
@@ -138,22 +142,26 @@ struct getdents_callback {
138}; 142};
139 143
140static int filldir(void * __buf, const char * name, int namlen, loff_t offset, 144static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
141 ino_t ino, unsigned int d_type) 145 u64 ino, unsigned int d_type)
142{ 146{
143 struct linux_dirent __user * dirent; 147 struct linux_dirent __user * dirent;
144 struct getdents_callback * buf = (struct getdents_callback *) __buf; 148 struct getdents_callback * buf = (struct getdents_callback *) __buf;
149 unsigned long d_ino;
145 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); 150 int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2);
146 151
147 buf->error = -EINVAL; /* only used if we fail.. */ 152 buf->error = -EINVAL; /* only used if we fail.. */
148 if (reclen > buf->count) 153 if (reclen > buf->count)
149 return -EINVAL; 154 return -EINVAL;
155 d_ino = ino;
156 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
157 return -EOVERFLOW;
150 dirent = buf->previous; 158 dirent = buf->previous;
151 if (dirent) { 159 if (dirent) {
152 if (__put_user(offset, &dirent->d_off)) 160 if (__put_user(offset, &dirent->d_off))
153 goto efault; 161 goto efault;
154 } 162 }
155 dirent = buf->current_dir; 163 dirent = buf->current_dir;
156 if (__put_user(ino, &dirent->d_ino)) 164 if (__put_user(d_ino, &dirent->d_ino))
157 goto efault; 165 goto efault;
158 if (__put_user(reclen, &dirent->d_reclen)) 166 if (__put_user(reclen, &dirent->d_reclen))
159 goto efault; 167 goto efault;
@@ -222,7 +230,7 @@ struct getdents_callback64 {
222}; 230};
223 231
224static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, 232static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
225 ino_t ino, unsigned int d_type) 233 u64 ino, unsigned int d_type)
226{ 234{
227 struct linux_dirent64 __user *dirent; 235 struct linux_dirent64 __user *dirent;
228 struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; 236 struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index d935fb9394e3..7bdb0ed443e1 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -773,7 +773,7 @@ int reiserfs_xattr_del(struct inode *inode, const char *name)
773 773
774static int 774static int
775reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, 775reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
776 loff_t offset, ino_t ino, unsigned int d_type) 776 loff_t offset, u64 ino, unsigned int d_type)
777{ 777{
778 struct dentry *xadir = (struct dentry *)buf; 778 struct dentry *xadir = (struct dentry *)buf;
779 779
@@ -851,7 +851,7 @@ struct reiserfs_chown_buf {
851/* XXX: If there is a better way to do this, I'd love to hear about it */ 851/* XXX: If there is a better way to do this, I'd love to hear about it */
852static int 852static int
853reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, 853reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
854 loff_t offset, ino_t ino, unsigned int d_type) 854 loff_t offset, u64 ino, unsigned int d_type)
855{ 855{
856 struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; 856 struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
857 struct dentry *xafile, *xadir = chown_buf->xadir; 857 struct dentry *xafile, *xadir = chown_buf->xadir;
@@ -1036,7 +1036,7 @@ struct reiserfs_listxattr_buf {
1036 1036
1037static int 1037static int
1038reiserfs_listxattr_filler(void *buf, const char *name, int namelen, 1038reiserfs_listxattr_filler(void *buf, const char *name, int namelen,
1039 loff_t offset, ino_t ino, unsigned int d_type) 1039 loff_t offset, u64 ino, unsigned int d_type)
1040{ 1040{
1041 struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; 1041 struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
1042 int len = 0; 1042 int len = 0;
diff --git a/fs/stat.c b/fs/stat.c
index 60a31d5e5966..bca07eb2003c 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -140,6 +140,8 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta
140 memset(&tmp, 0, sizeof(struct __old_kernel_stat)); 140 memset(&tmp, 0, sizeof(struct __old_kernel_stat));
141 tmp.st_dev = old_encode_dev(stat->dev); 141 tmp.st_dev = old_encode_dev(stat->dev);
142 tmp.st_ino = stat->ino; 142 tmp.st_ino = stat->ino;
143 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
144 return -EOVERFLOW;
143 tmp.st_mode = stat->mode; 145 tmp.st_mode = stat->mode;
144 tmp.st_nlink = stat->nlink; 146 tmp.st_nlink = stat->nlink;
145 if (tmp.st_nlink != stat->nlink) 147 if (tmp.st_nlink != stat->nlink)
@@ -210,6 +212,8 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
210 tmp.st_dev = new_encode_dev(stat->dev); 212 tmp.st_dev = new_encode_dev(stat->dev);
211#endif 213#endif
212 tmp.st_ino = stat->ino; 214 tmp.st_ino = stat->ino;
215 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
216 return -EOVERFLOW;
213 tmp.st_mode = stat->mode; 217 tmp.st_mode = stat->mode;
214 tmp.st_nlink = stat->nlink; 218 tmp.st_nlink = stat->nlink;
215 if (tmp.st_nlink != stat->nlink) 219 if (tmp.st_nlink != stat->nlink)
@@ -347,6 +351,8 @@ static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
347 tmp.st_rdev = huge_encode_dev(stat->rdev); 351 tmp.st_rdev = huge_encode_dev(stat->rdev);
348#endif 352#endif
349 tmp.st_ino = stat->ino; 353 tmp.st_ino = stat->ino;
354 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
355 return -EOVERFLOW;
350#ifdef STAT64_HAS_BROKEN_ST_INO 356#ifdef STAT64_HAS_BROKEN_ST_INO
351 tmp.__st_ino = stat->ino; 357 tmp.__st_ino = stat->ino;
352#endif 358#endif
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 91c0b2a32a90..7b61e94bf8fc 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1049,7 +1049,7 @@ int generic_osync_inode(struct inode *, struct address_space *, int);
1049 * This allows the kernel to read directories into kernel space or 1049 * This allows the kernel to read directories into kernel space or
1050 * to have different dirent layouts depending on the binary type. 1050 * to have different dirent layouts depending on the binary type.
1051 */ 1051 */
1052typedef int (*filldir_t)(void *, const char *, int, loff_t, ino_t, unsigned); 1052typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
1053 1053
1054struct block_device_operations { 1054struct block_device_operations {
1055 int (*open) (struct inode *, struct file *); 1055 int (*open) (struct inode *, struct file *);
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 8669291352db..679ef0d70b6b 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -57,7 +57,7 @@
57#include <linux/time.h> 57#include <linux/time.h>
58 58
59struct kstat { 59struct kstat {
60 unsigned long ino; 60 u64 ino;
61 dev_t dev; 61 dev_t dev;
62 umode_t mode; 62 umode_t mode;
63 unsigned int nlink; 63 unsigned int nlink;