vm: fix potential null deref
[minix.git] / servers / ext2 / stadir.c
blobd5a2459798f861a3b5f340d1941930d930c90d87
1 /* Created (MFS based):
2 * February 2010 (Evgeniy Ivanov)
3 */
5 #include "fs.h"
6 #include <string.h>
7 #include <sys/stat.h>
8 #include <sys/statfs.h>
9 #include <sys/statvfs.h>
10 #include "inode.h"
11 #include "super.h"
12 #include <minix/vfsif.h>
15 /*===========================================================================*
16 * stat_inode *
17 *===========================================================================*/
18 static int stat_inode(
19 register struct inode *rip, /* pointer to inode to stat */
20 endpoint_t who_e, /* Caller endpoint */
21 cp_grant_id_t gid /* grant for the stat buf */
24 /* Common code for stat and fstat system calls. */
26 struct stat statbuf;
27 mode_t mo;
28 int r, s;
30 /* Update the atime, ctime, and mtime fields in the inode, if need be. */
31 if (rip->i_update) update_times(rip);
33 /* Fill in the statbuf struct. */
34 mo = rip->i_mode & I_TYPE;
36 /* true iff special */
37 s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
39 memset(&statbuf, 0, sizeof(struct stat));
41 statbuf.st_dev = rip->i_dev;
42 statbuf.st_ino = rip->i_num;
43 statbuf.st_mode = rip->i_mode;
44 statbuf.st_nlink = rip->i_links_count;
45 statbuf.st_uid = rip->i_uid;
46 statbuf.st_gid = rip->i_gid;
47 statbuf.st_rdev = (s ? rip->i_block[0] : NO_DEV);
48 statbuf.st_size = rip->i_size;
49 statbuf.st_atime = rip->i_atime;
50 statbuf.st_mtime = rip->i_mtime;
51 statbuf.st_ctime = rip->i_ctime;
52 statbuf.st_blksize = rip->i_sp->s_block_size;
53 statbuf.st_blocks = rip->i_blocks;
55 /* Copy the struct to user space. */
56 r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
57 (size_t) sizeof(statbuf));
59 return(r);
63 /*===========================================================================*
64 * fs_fstatfs *
65 *===========================================================================*/
66 int fs_fstatfs()
68 struct statfs st;
69 struct inode *rip;
70 int r;
72 if((rip = find_inode(fs_dev, ROOT_INODE)) == NULL)
73 return(EINVAL);
75 st.f_bsize = rip->i_sp->s_block_size;
77 /* Copy the struct to user space. */
78 r = sys_safecopyto(fs_m_in.m_source, (cp_grant_id_t) fs_m_in.REQ_GRANT,
79 (vir_bytes) 0, (vir_bytes) &st, (size_t) sizeof(st));
81 return(r);
85 /*===========================================================================*
86 * fs_stat *
87 *===========================================================================*/
88 int fs_stat()
90 register int r; /* return value */
91 register struct inode *rip; /* target inode */
93 if ((rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
94 return(EINVAL);
96 r = stat_inode(rip, fs_m_in.m_source, (cp_grant_id_t) fs_m_in.REQ_GRANT);
97 put_inode(rip); /* release the inode */
98 return(r);
101 /*===========================================================================*
102 * fs_statvfs *
103 *===========================================================================*/
104 int fs_statvfs()
106 struct statvfs st;
107 struct super_block *sp;
108 int r;
110 sp = get_super(fs_dev);
112 st.f_bsize = sp->s_block_size;
113 st.f_frsize = sp->s_block_size;
114 st.f_blocks = sp->s_blocks_count;
115 st.f_bfree = sp->s_free_blocks_count;
116 st.f_bavail = sp->s_free_blocks_count - sp->s_r_blocks_count;
117 st.f_files = sp->s_inodes_count;
118 st.f_ffree = sp->s_free_inodes_count;
119 st.f_favail = sp->s_free_inodes_count;
120 st.f_fsid = fs_dev;
121 st.f_flag = (sp->s_rd_only == 1 ? ST_RDONLY : 0);
122 st.f_flag |= ST_NOTRUNC;
123 st.f_namemax = NAME_MAX;
125 /* Copy the struct to user space. */
126 r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT, 0, (vir_bytes) &st,
127 (phys_bytes) sizeof(st));
129 return(r);
132 /*===========================================================================*
133 * blockstats *
134 *===========================================================================*/
135 void fs_blockstats(u32_t *blocks, u32_t *free, u32_t *used)
137 struct super_block *sp = get_super(fs_dev);
139 *blocks = sp->s_blocks_count;
140 *free = sp->s_free_blocks_count;
141 *used = *blocks - *free;