xref: /minix3/minix/fs/mfs/stadir.c (revision 9866ad31fd560d01cf4e2a1c4ceaf27050cda8f6)
1433d6423SLionel Sambuc #include "fs.h"
2433d6423SLionel Sambuc #include <string.h>
3433d6423SLionel Sambuc #include <sys/stat.h>
4433d6423SLionel Sambuc #include <sys/statvfs.h>
5433d6423SLionel Sambuc #include "inode.h"
6433d6423SLionel Sambuc #include "super.h"
7433d6423SLionel Sambuc 
8433d6423SLionel Sambuc /*===========================================================================*
9433d6423SLionel Sambuc  *				estimate_blocks				     *
10433d6423SLionel Sambuc  *===========================================================================*/
estimate_blocks(struct inode * rip)11433d6423SLionel Sambuc static blkcnt_t estimate_blocks(struct inode *rip)
12433d6423SLionel Sambuc {
13433d6423SLionel Sambuc /* Return the number of 512-byte blocks used by this file. This includes space
14433d6423SLionel Sambuc  * used by data zones and indirect blocks (actually also zones). Reading in all
15433d6423SLionel Sambuc  * indirect blocks is too costly for a stat call, so we disregard holes and
16433d6423SLionel Sambuc  * return a conservative estimation.
17433d6423SLionel Sambuc  */
18433d6423SLionel Sambuc   blkcnt_t zones, sindirs, dindirs, nr_indirs, sq_indirs;
19433d6423SLionel Sambuc   unsigned int zone_size;
20433d6423SLionel Sambuc 
21433d6423SLionel Sambuc   /* Compute the number of zones used by the file. */
22433d6423SLionel Sambuc   zone_size = rip->i_sp->s_block_size << rip->i_sp->s_log_zone_size;
23433d6423SLionel Sambuc 
24433d6423SLionel Sambuc   zones = (blkcnt_t) ((rip->i_size + zone_size - 1) / zone_size);
25433d6423SLionel Sambuc 
26433d6423SLionel Sambuc   /* Compute the number of indirect blocks needed for that zone count. */
27433d6423SLionel Sambuc   nr_indirs = (blkcnt_t) rip->i_nindirs;
28433d6423SLionel Sambuc   sq_indirs = nr_indirs * nr_indirs;
29433d6423SLionel Sambuc 
30433d6423SLionel Sambuc   sindirs = (zones - (blkcnt_t) rip->i_ndzones + nr_indirs - 1) / nr_indirs;
31433d6423SLionel Sambuc   dindirs = (sindirs - 1 + sq_indirs - 1) / sq_indirs;
32433d6423SLionel Sambuc 
33433d6423SLionel Sambuc   /* Return the number of 512-byte blocks corresponding to the number of data
34433d6423SLionel Sambuc    * zones and indirect blocks.
35433d6423SLionel Sambuc    */
36433d6423SLionel Sambuc   return (zones + sindirs + dindirs) * (blkcnt_t) (zone_size / 512);
37433d6423SLionel Sambuc }
38433d6423SLionel Sambuc 
39433d6423SLionel Sambuc 
40ccaeedb2SDavid van Moolenbroek /*===========================================================================*
41ccaeedb2SDavid van Moolenbroek  *                             fs_stat					     *
42ccaeedb2SDavid van Moolenbroek  *===========================================================================*/
fs_stat(ino_t ino_nr,struct stat * statbuf)43ccaeedb2SDavid van Moolenbroek int fs_stat(ino_t ino_nr, struct stat *statbuf)
44ccaeedb2SDavid van Moolenbroek {
45ccaeedb2SDavid van Moolenbroek   struct inode *rip;
46433d6423SLionel Sambuc   mode_t mo;
47ccaeedb2SDavid van Moolenbroek   int s;
48ccaeedb2SDavid van Moolenbroek 
49ccaeedb2SDavid van Moolenbroek   if ((rip = get_inode(fs_dev, ino_nr)) == NULL)
50ccaeedb2SDavid van Moolenbroek 	return(EINVAL);
51433d6423SLionel Sambuc 
52433d6423SLionel Sambuc   /* Update the atime, ctime, and mtime fields in the inode, if need be. */
53433d6423SLionel Sambuc   if (rip->i_update) update_times(rip);
54433d6423SLionel Sambuc 
55433d6423SLionel Sambuc   /* Fill in the statbuf struct. */
56433d6423SLionel Sambuc   mo = rip->i_mode & I_TYPE;
57433d6423SLionel Sambuc 
58433d6423SLionel Sambuc   /* true iff special */
59433d6423SLionel Sambuc   s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
60433d6423SLionel Sambuc 
61ccaeedb2SDavid van Moolenbroek   statbuf->st_mode = (mode_t) rip->i_mode;
62ccaeedb2SDavid van Moolenbroek   statbuf->st_nlink = (nlink_t) rip->i_nlinks;
63ccaeedb2SDavid van Moolenbroek   statbuf->st_uid = rip->i_uid;
64ccaeedb2SDavid van Moolenbroek   statbuf->st_gid = rip->i_gid;
65ccaeedb2SDavid van Moolenbroek   statbuf->st_rdev = (s ? (dev_t)rip->i_zone[0] : NO_DEV);
66ccaeedb2SDavid van Moolenbroek   statbuf->st_size = rip->i_size;
67ccaeedb2SDavid van Moolenbroek   statbuf->st_atime = rip->i_atime;
68ccaeedb2SDavid van Moolenbroek   statbuf->st_mtime = rip->i_mtime;
69ccaeedb2SDavid van Moolenbroek   statbuf->st_ctime = rip->i_ctime;
70ccaeedb2SDavid van Moolenbroek   statbuf->st_blksize = lmfs_fs_block_size();
71ccaeedb2SDavid van Moolenbroek   statbuf->st_blocks = estimate_blocks(rip);
72433d6423SLionel Sambuc 
73ccaeedb2SDavid van Moolenbroek   put_inode(rip);		/* release the inode */
74433d6423SLionel Sambuc 
75ccaeedb2SDavid van Moolenbroek   return(OK);
76433d6423SLionel Sambuc }
77433d6423SLionel Sambuc 
78ccaeedb2SDavid van Moolenbroek 
79433d6423SLionel Sambuc /*===========================================================================*
80433d6423SLionel Sambuc  *				fs_statvfs				     *
81433d6423SLionel Sambuc  *===========================================================================*/
fs_statvfs(struct statvfs * st)82ccaeedb2SDavid van Moolenbroek int fs_statvfs(struct statvfs *st)
83433d6423SLionel Sambuc {
84433d6423SLionel Sambuc   struct super_block *sp;
85ccaeedb2SDavid van Moolenbroek   int scale;
86433d6423SLionel Sambuc 
87*4472b590SDavid van Moolenbroek   sp = &superblock;
88433d6423SLionel Sambuc 
89433d6423SLionel Sambuc   scale = sp->s_log_zone_size;
90433d6423SLionel Sambuc 
911311233cSDavid van Moolenbroek   st->f_blocks = sp->s_zones;
921311233cSDavid van Moolenbroek   st->f_bfree = sp->s_zones - used_zones;
93ccaeedb2SDavid van Moolenbroek   st->f_bavail = st->f_bfree;
94433d6423SLionel Sambuc 
95ccaeedb2SDavid van Moolenbroek   st->f_bsize = sp->s_block_size << scale;
96ccaeedb2SDavid van Moolenbroek   st->f_frsize = sp->s_block_size;
97ccaeedb2SDavid van Moolenbroek   st->f_iosize = st->f_frsize;
98ccaeedb2SDavid van Moolenbroek   st->f_files = sp->s_ninodes;
99ccaeedb2SDavid van Moolenbroek   st->f_ffree = count_free_bits(sp, IMAP);
100ccaeedb2SDavid van Moolenbroek   st->f_favail = st->f_ffree;
101ccaeedb2SDavid van Moolenbroek   st->f_namemax = MFS_DIRSIZ;
102433d6423SLionel Sambuc 
103ccaeedb2SDavid van Moolenbroek   return(OK);
104433d6423SLionel Sambuc }
105