root/fs/stat.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cp_old_stat
  2. cp_new_stat
  3. sys_stat
  4. sys_newstat
  5. sys_lstat
  6. sys_newlstat
  7. sys_fstat
  8. sys_newfstat
  9. sys_readlink

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

/* [previous][next][first][last][top][bottom][index][help] */