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

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