at v3.0 11 kB view raw
1/* 2 * linux/fs/stat.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 */ 6 7#include <linux/module.h> 8#include <linux/mm.h> 9#include <linux/errno.h> 10#include <linux/file.h> 11#include <linux/highuid.h> 12#include <linux/fs.h> 13#include <linux/namei.h> 14#include <linux/security.h> 15#include <linux/syscalls.h> 16#include <linux/pagemap.h> 17 18#include <asm/uaccess.h> 19#include <asm/unistd.h> 20 21void generic_fillattr(struct inode *inode, struct kstat *stat) 22{ 23 stat->dev = inode->i_sb->s_dev; 24 stat->ino = inode->i_ino; 25 stat->mode = inode->i_mode; 26 stat->nlink = inode->i_nlink; 27 stat->uid = inode->i_uid; 28 stat->gid = inode->i_gid; 29 stat->rdev = inode->i_rdev; 30 stat->atime = inode->i_atime; 31 stat->mtime = inode->i_mtime; 32 stat->ctime = inode->i_ctime; 33 stat->size = i_size_read(inode); 34 stat->blocks = inode->i_blocks; 35 stat->blksize = (1 << inode->i_blkbits); 36} 37 38EXPORT_SYMBOL(generic_fillattr); 39 40int vfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 41{ 42 struct inode *inode = dentry->d_inode; 43 int retval; 44 45 retval = security_inode_getattr(mnt, dentry); 46 if (retval) 47 return retval; 48 49 if (inode->i_op->getattr) 50 return inode->i_op->getattr(mnt, dentry, stat); 51 52 generic_fillattr(inode, stat); 53 return 0; 54} 55 56EXPORT_SYMBOL(vfs_getattr); 57 58int vfs_fstat(unsigned int fd, struct kstat *stat) 59{ 60 struct file *f = fget(fd); 61 int error = -EBADF; 62 63 if (f) { 64 error = vfs_getattr(f->f_path.mnt, f->f_path.dentry, stat); 65 fput(f); 66 } 67 return error; 68} 69EXPORT_SYMBOL(vfs_fstat); 70 71int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, 72 int flag) 73{ 74 struct path path; 75 int error = -EINVAL; 76 int lookup_flags = 0; 77 78 if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | 79 AT_EMPTY_PATH)) != 0) 80 goto out; 81 82 if (!(flag & AT_SYMLINK_NOFOLLOW)) 83 lookup_flags |= LOOKUP_FOLLOW; 84 if (flag & AT_NO_AUTOMOUNT) 85 lookup_flags |= LOOKUP_NO_AUTOMOUNT; 86 if (flag & AT_EMPTY_PATH) 87 lookup_flags |= LOOKUP_EMPTY; 88 89 error = user_path_at(dfd, filename, lookup_flags, &path); 90 if (error) 91 goto out; 92 93 error = vfs_getattr(path.mnt, path.dentry, stat); 94 path_put(&path); 95out: 96 return error; 97} 98EXPORT_SYMBOL(vfs_fstatat); 99 100int vfs_stat(const char __user *name, struct kstat *stat) 101{ 102 return vfs_fstatat(AT_FDCWD, name, stat, 0); 103} 104EXPORT_SYMBOL(vfs_stat); 105 106int vfs_lstat(const char __user *name, struct kstat *stat) 107{ 108 return vfs_fstatat(AT_FDCWD, name, stat, AT_SYMLINK_NOFOLLOW); 109} 110EXPORT_SYMBOL(vfs_lstat); 111 112 113#ifdef __ARCH_WANT_OLD_STAT 114 115/* 116 * For backward compatibility? Maybe this should be moved 117 * into arch/i386 instead? 118 */ 119static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * statbuf) 120{ 121 static int warncount = 5; 122 struct __old_kernel_stat tmp; 123 124 if (warncount > 0) { 125 warncount--; 126 printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n", 127 current->comm); 128 } else if (warncount < 0) { 129 /* it's laughable, but... */ 130 warncount = 0; 131 } 132 133 memset(&tmp, 0, sizeof(struct __old_kernel_stat)); 134 tmp.st_dev = old_encode_dev(stat->dev); 135 tmp.st_ino = stat->ino; 136 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) 137 return -EOVERFLOW; 138 tmp.st_mode = stat->mode; 139 tmp.st_nlink = stat->nlink; 140 if (tmp.st_nlink != stat->nlink) 141 return -EOVERFLOW; 142 SET_UID(tmp.st_uid, stat->uid); 143 SET_GID(tmp.st_gid, stat->gid); 144 tmp.st_rdev = old_encode_dev(stat->rdev); 145#if BITS_PER_LONG == 32 146 if (stat->size > MAX_NON_LFS) 147 return -EOVERFLOW; 148#endif 149 tmp.st_size = stat->size; 150 tmp.st_atime = stat->atime.tv_sec; 151 tmp.st_mtime = stat->mtime.tv_sec; 152 tmp.st_ctime = stat->ctime.tv_sec; 153 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 154} 155 156SYSCALL_DEFINE2(stat, const char __user *, filename, 157 struct __old_kernel_stat __user *, statbuf) 158{ 159 struct kstat stat; 160 int error; 161 162 error = vfs_stat(filename, &stat); 163 if (error) 164 return error; 165 166 return cp_old_stat(&stat, statbuf); 167} 168 169SYSCALL_DEFINE2(lstat, const char __user *, filename, 170 struct __old_kernel_stat __user *, statbuf) 171{ 172 struct kstat stat; 173 int error; 174 175 error = vfs_lstat(filename, &stat); 176 if (error) 177 return error; 178 179 return cp_old_stat(&stat, statbuf); 180} 181 182SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf) 183{ 184 struct kstat stat; 185 int error = vfs_fstat(fd, &stat); 186 187 if (!error) 188 error = cp_old_stat(&stat, statbuf); 189 190 return error; 191} 192 193#endif /* __ARCH_WANT_OLD_STAT */ 194 195static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) 196{ 197 struct stat tmp; 198 199#if BITS_PER_LONG == 32 200 if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) 201 return -EOVERFLOW; 202#else 203 if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) 204 return -EOVERFLOW; 205#endif 206 207 memset(&tmp, 0, sizeof(tmp)); 208#if BITS_PER_LONG == 32 209 tmp.st_dev = old_encode_dev(stat->dev); 210#else 211 tmp.st_dev = new_encode_dev(stat->dev); 212#endif 213 tmp.st_ino = stat->ino; 214 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) 215 return -EOVERFLOW; 216 tmp.st_mode = stat->mode; 217 tmp.st_nlink = stat->nlink; 218 if (tmp.st_nlink != stat->nlink) 219 return -EOVERFLOW; 220 SET_UID(tmp.st_uid, stat->uid); 221 SET_GID(tmp.st_gid, stat->gid); 222#if BITS_PER_LONG == 32 223 tmp.st_rdev = old_encode_dev(stat->rdev); 224#else 225 tmp.st_rdev = new_encode_dev(stat->rdev); 226#endif 227#if BITS_PER_LONG == 32 228 if (stat->size > MAX_NON_LFS) 229 return -EOVERFLOW; 230#endif 231 tmp.st_size = stat->size; 232 tmp.st_atime = stat->atime.tv_sec; 233 tmp.st_mtime = stat->mtime.tv_sec; 234 tmp.st_ctime = stat->ctime.tv_sec; 235#ifdef STAT_HAVE_NSEC 236 tmp.st_atime_nsec = stat->atime.tv_nsec; 237 tmp.st_mtime_nsec = stat->mtime.tv_nsec; 238 tmp.st_ctime_nsec = stat->ctime.tv_nsec; 239#endif 240 tmp.st_blocks = stat->blocks; 241 tmp.st_blksize = stat->blksize; 242 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 243} 244 245SYSCALL_DEFINE2(newstat, const char __user *, filename, 246 struct stat __user *, statbuf) 247{ 248 struct kstat stat; 249 int error = vfs_stat(filename, &stat); 250 251 if (error) 252 return error; 253 return cp_new_stat(&stat, statbuf); 254} 255 256SYSCALL_DEFINE2(newlstat, const char __user *, filename, 257 struct stat __user *, statbuf) 258{ 259 struct kstat stat; 260 int error; 261 262 error = vfs_lstat(filename, &stat); 263 if (error) 264 return error; 265 266 return cp_new_stat(&stat, statbuf); 267} 268 269#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT) 270SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename, 271 struct stat __user *, statbuf, int, flag) 272{ 273 struct kstat stat; 274 int error; 275 276 error = vfs_fstatat(dfd, filename, &stat, flag); 277 if (error) 278 return error; 279 return cp_new_stat(&stat, statbuf); 280} 281#endif 282 283SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf) 284{ 285 struct kstat stat; 286 int error = vfs_fstat(fd, &stat); 287 288 if (!error) 289 error = cp_new_stat(&stat, statbuf); 290 291 return error; 292} 293 294SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname, 295 char __user *, buf, int, bufsiz) 296{ 297 struct path path; 298 int error; 299 300 if (bufsiz <= 0) 301 return -EINVAL; 302 303 error = user_path_at(dfd, pathname, LOOKUP_EMPTY, &path); 304 if (!error) { 305 struct inode *inode = path.dentry->d_inode; 306 307 error = -EINVAL; 308 if (inode->i_op->readlink) { 309 error = security_inode_readlink(path.dentry); 310 if (!error) { 311 touch_atime(path.mnt, path.dentry); 312 error = inode->i_op->readlink(path.dentry, 313 buf, bufsiz); 314 } 315 } 316 path_put(&path); 317 } 318 return error; 319} 320 321SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf, 322 int, bufsiz) 323{ 324 return sys_readlinkat(AT_FDCWD, path, buf, bufsiz); 325} 326 327 328/* ---------- LFS-64 ----------- */ 329#ifdef __ARCH_WANT_STAT64 330 331static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf) 332{ 333 struct stat64 tmp; 334 335 memset(&tmp, 0, sizeof(struct stat64)); 336#ifdef CONFIG_MIPS 337 /* mips has weird padding, so we don't get 64 bits there */ 338 if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) 339 return -EOVERFLOW; 340 tmp.st_dev = new_encode_dev(stat->dev); 341 tmp.st_rdev = new_encode_dev(stat->rdev); 342#else 343 tmp.st_dev = huge_encode_dev(stat->dev); 344 tmp.st_rdev = huge_encode_dev(stat->rdev); 345#endif 346 tmp.st_ino = stat->ino; 347 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) 348 return -EOVERFLOW; 349#ifdef STAT64_HAS_BROKEN_ST_INO 350 tmp.__st_ino = stat->ino; 351#endif 352 tmp.st_mode = stat->mode; 353 tmp.st_nlink = stat->nlink; 354 tmp.st_uid = stat->uid; 355 tmp.st_gid = stat->gid; 356 tmp.st_atime = stat->atime.tv_sec; 357 tmp.st_atime_nsec = stat->atime.tv_nsec; 358 tmp.st_mtime = stat->mtime.tv_sec; 359 tmp.st_mtime_nsec = stat->mtime.tv_nsec; 360 tmp.st_ctime = stat->ctime.tv_sec; 361 tmp.st_ctime_nsec = stat->ctime.tv_nsec; 362 tmp.st_size = stat->size; 363 tmp.st_blocks = stat->blocks; 364 tmp.st_blksize = stat->blksize; 365 return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; 366} 367 368SYSCALL_DEFINE2(stat64, const char __user *, filename, 369 struct stat64 __user *, statbuf) 370{ 371 struct kstat stat; 372 int error = vfs_stat(filename, &stat); 373 374 if (!error) 375 error = cp_new_stat64(&stat, statbuf); 376 377 return error; 378} 379 380SYSCALL_DEFINE2(lstat64, const char __user *, filename, 381 struct stat64 __user *, statbuf) 382{ 383 struct kstat stat; 384 int error = vfs_lstat(filename, &stat); 385 386 if (!error) 387 error = cp_new_stat64(&stat, statbuf); 388 389 return error; 390} 391 392SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf) 393{ 394 struct kstat stat; 395 int error = vfs_fstat(fd, &stat); 396 397 if (!error) 398 error = cp_new_stat64(&stat, statbuf); 399 400 return error; 401} 402 403SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename, 404 struct stat64 __user *, statbuf, int, flag) 405{ 406 struct kstat stat; 407 int error; 408 409 error = vfs_fstatat(dfd, filename, &stat, flag); 410 if (error) 411 return error; 412 return cp_new_stat64(&stat, statbuf); 413} 414#endif /* __ARCH_WANT_STAT64 */ 415 416/* Caller is here responsible for sufficient locking (ie. inode->i_lock) */ 417void __inode_add_bytes(struct inode *inode, loff_t bytes) 418{ 419 inode->i_blocks += bytes >> 9; 420 bytes &= 511; 421 inode->i_bytes += bytes; 422 if (inode->i_bytes >= 512) { 423 inode->i_blocks++; 424 inode->i_bytes -= 512; 425 } 426} 427 428void inode_add_bytes(struct inode *inode, loff_t bytes) 429{ 430 spin_lock(&inode->i_lock); 431 __inode_add_bytes(inode, bytes); 432 spin_unlock(&inode->i_lock); 433} 434 435EXPORT_SYMBOL(inode_add_bytes); 436 437void inode_sub_bytes(struct inode *inode, loff_t bytes) 438{ 439 spin_lock(&inode->i_lock); 440 inode->i_blocks -= bytes >> 9; 441 bytes &= 511; 442 if (inode->i_bytes < bytes) { 443 inode->i_blocks--; 444 inode->i_bytes += 512; 445 } 446 inode->i_bytes -= bytes; 447 spin_unlock(&inode->i_lock); 448} 449 450EXPORT_SYMBOL(inode_sub_bytes); 451 452loff_t inode_get_bytes(struct inode *inode) 453{ 454 loff_t ret; 455 456 spin_lock(&inode->i_lock); 457 ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; 458 spin_unlock(&inode->i_lock); 459 return ret; 460} 461 462EXPORT_SYMBOL(inode_get_bytes); 463 464void inode_set_bytes(struct inode *inode, loff_t bytes) 465{ 466 /* Caller is here responsible for sufficient locking 467 * (ie. inode->i_lock) */ 468 inode->i_blocks = bytes >> 9; 469 inode->i_bytes = bytes & 511; 470} 471 472EXPORT_SYMBOL(inode_set_bytes);