home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / stat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  4.9 KB  |  206 lines

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