|
|
1.1.1.2 root 1: /*
2: * linux/fs/stat.c
3: *
1.1.1.7 root 4: * Copyright (C) 1991, 1992 Linus Torvalds
1.1.1.2 root 5: */
6:
1.1.1.7 root 7: #include <linux/errno.h>
1.1.1.5 root 8: #include <linux/stat.h>
1.1 root 9: #include <linux/fs.h>
10: #include <linux/sched.h>
11: #include <linux/kernel.h>
12: #include <asm/segment.h>
13:
1.1.1.5 root 14: static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
1.1 root 15: {
1.1.1.5 root 16: struct old_stat tmp;
1.1 root 17:
1.1.1.5 root 18: if (inode->i_ino & 0xffff0000)
19: printk("Warning: using old stat() call on bigfs\n");
20: verify_area(statbuf,sizeof (*statbuf));
1.1 root 21: tmp.st_dev = inode->i_dev;
1.1.1.4 root 22: tmp.st_ino = inode->i_ino;
1.1 root 23: tmp.st_mode = inode->i_mode;
1.1.1.4 root 24: tmp.st_nlink = inode->i_nlink;
1.1 root 25: tmp.st_uid = inode->i_uid;
26: tmp.st_gid = inode->i_gid;
1.1.1.4 root 27: tmp.st_rdev = inode->i_rdev;
1.1.1.8 ! root 28: tmp.st_size = inode->i_size;
1.1 root 29: tmp.st_atime = inode->i_atime;
30: tmp.st_mtime = inode->i_mtime;
31: tmp.st_ctime = inode->i_ctime;
1.1.1.5 root 32: memcpy_tofs(statbuf,&tmp,sizeof(tmp));
1.1 root 33: }
34:
1.1.1.5 root 35: static void cp_new_stat(struct inode * inode, struct new_stat * statbuf)
36: {
37: struct new_stat tmp = {0, };
1.1.1.6 root 38: unsigned int blocks, indirect;
1.1.1.5 root 39:
40: verify_area(statbuf,sizeof (*statbuf));
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;
1.1.1.8 ! root 48: tmp.st_size = inode->i_size;
1.1.1.5 root 49: tmp.st_atime = inode->i_atime;
50: tmp.st_mtime = inode->i_mtime;
51: tmp.st_ctime = inode->i_ctime;
1.1.1.6 root 52: /*
1.1.1.8 ! root 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.
1.1.1.6 root 59: */
1.1.1.8 ! root 60: if (!inode->i_blksize) {
! 61: blocks = (tmp.st_size + 511) / 512;
! 62: if (blocks > 10) {
! 63: indirect = (blocks - 11)/256+1;
! 64: if (blocks > 10+256) {
! 65: indirect += (blocks - 267)/(256*256)+1;
! 66: if (blocks > 10+256+256*256)
! 67: indirect++;
! 68: }
! 69: blocks += indirect;
1.1.1.6 root 70: }
1.1.1.8 ! root 71: tmp.st_blocks = blocks;
! 72: } else
! 73: tmp.st_blocks = (inode->i_blocks * inode->i_blksize) / 512;
! 74: tmp.st_blksize = 512;
1.1.1.5 root 75: memcpy_tofs(statbuf,&tmp,sizeof(tmp));
76: }
77:
78: int sys_stat(char * filename, struct old_stat * statbuf)
79: {
80: struct inode * inode;
1.1.1.8 ! root 81: int error;
1.1.1.5 root 82:
1.1.1.8 ! root 83: error = namei(filename,&inode);
! 84: if (error)
! 85: return error;
1.1.1.5 root 86: cp_old_stat(inode,statbuf);
87: iput(inode);
88: return 0;
89: }
90:
91: int sys_newstat(char * filename, struct new_stat * statbuf)
1.1 root 92: {
1.1.1.4 root 93: struct inode * inode;
1.1.1.8 ! root 94: int error;
1.1 root 95:
1.1.1.8 ! root 96: error = namei(filename,&inode);
! 97: if (error)
! 98: return error;
1.1.1.5 root 99: cp_new_stat(inode,statbuf);
1.1 root 100: iput(inode);
1.1.1.2 root 101: return 0;
1.1 root 102: }
103:
1.1.1.5 root 104: int sys_lstat(char * filename, struct old_stat * statbuf)
1.1.1.3 root 105: {
1.1.1.4 root 106: struct inode * inode;
1.1.1.8 ! root 107: int error;
1.1.1.3 root 108:
1.1.1.8 ! root 109: error = lnamei(filename,&inode);
! 110: if (error)
! 111: return error;
1.1.1.5 root 112: cp_old_stat(inode,statbuf);
1.1.1.3 root 113: iput(inode);
114: return 0;
115: }
116:
1.1.1.5 root 117: int sys_newlstat(char * filename, struct new_stat * statbuf)
118: {
119: struct inode * inode;
1.1.1.8 ! root 120: int error;
1.1.1.5 root 121:
1.1.1.8 ! root 122: error = lnamei(filename,&inode);
! 123: if (error)
! 124: return error;
1.1.1.5 root 125: cp_new_stat(inode,statbuf);
126: iput(inode);
127: return 0;
128: }
129:
130: int sys_fstat(unsigned int fd, struct old_stat * statbuf)
131: {
132: struct file * f;
133: struct inode * inode;
134:
135: if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
136: return -EBADF;
137: cp_old_stat(inode,statbuf);
138: return 0;
139: }
140:
141: int sys_newfstat(unsigned int fd, struct new_stat * statbuf)
1.1 root 142: {
143: struct file * f;
1.1.1.4 root 144: struct inode * inode;
1.1 root 145:
146: if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
1.1.1.2 root 147: return -EBADF;
1.1.1.5 root 148: cp_new_stat(inode,statbuf);
1.1.1.2 root 149: return 0;
1.1 root 150: }
1.1.1.3 root 151:
152: int sys_readlink(const char * path, char * buf, int bufsiz)
153: {
1.1.1.4 root 154: struct inode * inode;
1.1.1.8 ! root 155: int error;
1.1.1.3 root 156:
157: if (bufsiz <= 0)
1.1.1.4 root 158: return -EINVAL;
1.1.1.3 root 159: verify_area(buf,bufsiz);
1.1.1.8 ! root 160: error = lnamei(path,&inode);
! 161: if (error)
! 162: return error;
1.1.1.4 root 163: if (!inode->i_op || !inode->i_op->readlink) {
164: iput(inode);
165: return -EINVAL;
1.1.1.3 root 166: }
1.1.1.4 root 167: return inode->i_op->readlink(inode,buf,bufsiz);
1.1.1.3 root 168: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.