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/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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 }

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