home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / stat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-01  |  4.7 KB  |  202 lines

  1. /*
  2.  *  linux/fs/stat.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  */
  6.  
  7. #include <linux/errno.h>
  8. #include <linux/stat.h>
  9. #include <linux/fs.h>
  10. #include <linux/sched.h>
  11. #include <linux/kernel.h>
  12. #include <asm/segment.h>
  13.  
  14. static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
  15. {
  16.     struct old_stat tmp;
  17.  
  18.     printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
  19.         current->comm);
  20.     tmp.st_dev = inode->i_dev;
  21.     tmp.st_ino = inode->i_ino;
  22.     tmp.st_mode = inode->i_mode;
  23.     tmp.st_nlink = inode->i_nlink;
  24.     tmp.st_uid = inode->i_uid;
  25.     tmp.st_gid = inode->i_gid;
  26.     tmp.st_rdev = inode->i_rdev;
  27.     tmp.st_size = inode->i_size;
  28.     tmp.st_atime = inode->i_atime;
  29.     tmp.st_mtime = inode->i_mtime;
  30.     tmp.st_ctime = inode->i_ctime;
  31.     memcpy_tofs(statbuf,&tmp,sizeof(tmp));
  32. }
  33.  
  34. static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
  35. {
  36.     struct new_stat tmp = {0, };
  37.     unsigned int blocks, indirect;
  38.  
  39.     tmp.st_dev = inode->i_dev;
  40.     tmp.st_ino = inode->i_ino;
  41.     tmp.st_mode = inode->i_mode;
  42.     tmp.st_nlink = inode->i_nlink;
  43.     tmp.st_uid = inode->i_uid;
  44.     tmp.st_gid = inode->i_gid;
  45.     tmp.st_rdev = inode->i_rdev;
  46.     tmp.st_size = inode->i_size;
  47.     tmp.st_atime = inode->i_atime;
  48.     tmp.st_mtime = inode->i_mtime;
  49.     tmp.st_ctime = inode->i_ctime;
  50. /*
  51.  * st_blocks and st_blksize are approximated with a simple algorithm if
  52.  * they aren't supported directly by the filesystem. The minix and msdos
  53.  * filesystems don't keep track of blocks, so they would either have to
  54.  * be counted explicitly (by delving into the file itself), or by using
  55.  * this simple algorithm to get a reasonable (although not 100% accurate)
  56.  * value.
  57.  */
  58.  
  59. /*
  60.  * Use minix fs values for the number of direct and indirect blocks.  The
  61.  * count is now exact for the minix fs except that it counts zero blocks.
  62.  * Everything is in BLOCK_SIZE'd units until the assignment to
  63.  * tmp.st_blksize.
  64.  */
  65. #define D_B   7
  66. #define I_B   (BLOCK_SIZE / sizeof(unsigned short))
  67.  
  68.     if (!inode->i_blksize) {
  69.         blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
  70.         if (blocks > D_B) {
  71.             indirect = (blocks - D_B + I_B - 1) / I_B;
  72.             blocks += indirect;
  73.             if (indirect > 1) {
  74.                 indirect = (indirect - 1 + I_B - 1) / I_B;
  75.                 blocks += indirect;
  76.                 if (indirect > 1)
  77.                     blocks++;
  78.             }
  79.         }
  80.         tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
  81.         tmp.st_blksize = BLOCK_SIZE;
  82.     } else {
  83.         tmp.st_blocks = inode->i_blocks;
  84.         tmp.st_blksize = inode->i_blksize;
  85.     }
  86.     memcpy_tofs(statbuf,&tmp,sizeof(tmp));
  87. }
  88.  
  89. asmlinkage int sys_stat(char * filename, struct old_stat * statbuf)
  90. {
  91.     struct inode * inode;
  92.     int error;
  93.  
  94.     error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
  95.     if (error)
  96.         return error;
  97.     error = namei(filename,&inode);
  98.     if (error)
  99.         return error;
  100.     cp_old_stat(inode,statbuf);
  101.     iput(inode);
  102.     return 0;
  103. }
  104.  
  105. asmlinkage int sys_newstat(char * filename, struct new_stat * statbuf)
  106. {
  107.     struct inode * inode;
  108.     int error;
  109.  
  110.     error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
  111.     if (error)
  112.         return error;
  113.     error = namei(filename,&inode);
  114.     if (error)
  115.         return error;
  116.     cp_new_stat(inode,statbuf);
  117.     iput(inode);
  118.     return 0;
  119. }
  120.  
  121. asmlinkage int sys_lstat(char * filename, struct old_stat * statbuf)
  122. {
  123.     struct inode * inode;
  124.     int error;
  125.  
  126.     error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
  127.     if (error)
  128.         return error;
  129.     error = lnamei(filename,&inode);
  130.     if (error)
  131.         return error;
  132.     cp_old_stat(inode,statbuf);
  133.     iput(inode);
  134.     return 0;
  135. }
  136.  
  137. asmlinkage int sys_newlstat(char * filename, struct new_stat * statbuf)
  138. {
  139.     struct inode * inode;
  140.     int error;
  141.  
  142.     error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
  143.     if (error)
  144.         return error;
  145.     error = lnamei(filename,&inode);
  146.     if (error)
  147.         return error;
  148.     cp_new_stat(inode,statbuf);
  149.     iput(inode);
  150.     return 0;
  151. }
  152.  
  153. asmlinkage int sys_fstat(unsigned int fd, struct old_stat * statbuf)
  154. {
  155.     struct file * f;
  156.     struct inode * inode;
  157.     int error;
  158.  
  159.     error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
  160.     if (error)
  161.         return error;
  162.     if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
  163.         return -EBADF;
  164.     cp_old_stat(inode,statbuf);
  165.     return 0;
  166. }
  167.  
  168. asmlinkage int sys_newfstat(unsigned int fd, struct new_stat * statbuf)
  169. {
  170.     struct file * f;
  171.     struct inode * inode;
  172.     int error;
  173.  
  174.     error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
  175.     if (error)
  176.         return error;
  177.     if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
  178.         return -EBADF;
  179.     cp_new_stat(inode,statbuf);
  180.     return 0;
  181. }
  182.  
  183. asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz)
  184. {
  185.     struct inode * inode;
  186.     int error;
  187.  
  188.     if (bufsiz <= 0)
  189.         return -EINVAL;
  190.     error = verify_area(VERIFY_WRITE,buf,bufsiz);
  191.     if (error)
  192.         return error;
  193.     error = lnamei(path,&inode);
  194.     if (error)
  195.         return error;
  196.     if (!inode->i_op || !inode->i_op->readlink) {
  197.         iput(inode);
  198.         return -EINVAL;
  199.     }
  200.     return inode->i_op->readlink(inode,buf,bufsiz);
  201. }
  202.