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

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