5 #include <sys/statfs.h>
6 #include <sys/statvfs.h>
9 #include <minix/vfsif.h>
11 /*===========================================================================*
13 *===========================================================================*/
14 static blkcnt_t
estimate_blocks(struct inode
*rip
)
16 /* Return the number of 512-byte blocks used by this file. This includes space
17 * used by data zones and indirect blocks (actually also zones). Reading in all
18 * indirect blocks is too costly for a stat call, so we disregard holes and
19 * return a conservative estimation.
21 blkcnt_t zones
, sindirs
, dindirs
, nr_indirs
, sq_indirs
;
22 unsigned int zone_size
;
24 /* Compute the number of zones used by the file. */
25 zone_size
= rip
->i_sp
->s_block_size
<< rip
->i_sp
->s_log_zone_size
;
27 zones
= (blkcnt_t
) ((rip
->i_size
+ zone_size
- 1) / zone_size
);
29 /* Compute the number of indirect blocks needed for that zone count. */
30 nr_indirs
= (blkcnt_t
) rip
->i_nindirs
;
31 sq_indirs
= nr_indirs
* nr_indirs
;
33 sindirs
= (zones
- (blkcnt_t
) rip
->i_ndzones
+ nr_indirs
- 1) / nr_indirs
;
34 dindirs
= (sindirs
- 1 + sq_indirs
- 1) / sq_indirs
;
36 /* Return the number of 512-byte blocks corresponding to the number of data
37 * zones and indirect blocks.
39 return (zones
+ sindirs
+ dindirs
) * (blkcnt_t
) (zone_size
/ 512);
42 /*===========================================================================*
44 *===========================================================================*/
45 static int stat_inode(
46 register struct inode
*rip
, /* pointer to inode to stat */
47 endpoint_t who_e
, /* Caller endpoint */
48 cp_grant_id_t gid
/* grant for the stat buf */
51 /* Common code for stat and fstat system calls. */
57 /* Update the atime, ctime, and mtime fields in the inode, if need be. */
58 if (rip
->i_update
) update_times(rip
);
60 /* Fill in the statbuf struct. */
61 mo
= rip
->i_mode
& I_TYPE
;
63 /* true iff special */
64 s
= (mo
== I_CHAR_SPECIAL
|| mo
== I_BLOCK_SPECIAL
);
66 memset(&statbuf
, 0, sizeof(struct stat
));
68 statbuf
.st_dev
= rip
->i_dev
;
69 statbuf
.st_ino
= rip
->i_num
;
70 statbuf
.st_mode
= rip
->i_mode
;
71 statbuf
.st_nlink
= rip
->i_nlinks
;
72 statbuf
.st_uid
= rip
->i_uid
;
73 statbuf
.st_gid
= rip
->i_gid
;
74 statbuf
.st_rdev
= (s
? (dev_t
) rip
->i_zone
[0] : NO_DEV
);
75 statbuf
.st_size
= rip
->i_size
;
76 statbuf
.st_atime
= rip
->i_atime
;
77 statbuf
.st_mtime
= rip
->i_mtime
;
78 statbuf
.st_ctime
= rip
->i_ctime
;
79 statbuf
.st_blksize
= lmfs_fs_block_size();
80 statbuf
.st_blocks
= estimate_blocks(rip
);
82 /* Copy the struct to user space. */
83 r
= sys_safecopyto(who_e
, gid
, (vir_bytes
) 0, (vir_bytes
) &statbuf
,
84 (size_t) sizeof(statbuf
));
89 /*===========================================================================*
91 *===========================================================================*/
98 if((rip
= find_inode(fs_dev
, ROOT_INODE
)) == NULL
)
101 st
.f_bsize
= rip
->i_sp
->s_block_size
;
103 /* Copy the struct to user space. */
104 r
= sys_safecopyto(fs_m_in
.m_source
, (cp_grant_id_t
) fs_m_in
.REQ_GRANT
,
105 (vir_bytes
) 0, (vir_bytes
) &st
, (size_t) sizeof(st
));
111 /*===========================================================================*
113 *===========================================================================*/
117 struct super_block
*sp
;
121 sp
= get_super(fs_dev
);
123 scale
= sp
->s_log_zone_size
;
125 fs_blockstats((u32_t
*) &st
.f_blocks
, (u32_t
*) &st
.f_bfree
, &used
);
126 st
.f_bavail
= st
.f_bfree
;
128 st
.f_bsize
= sp
->s_block_size
<< scale
;
129 st
.f_frsize
= sp
->s_block_size
;
130 st
.f_files
= sp
->s_ninodes
;
131 st
.f_ffree
= count_free_bits(sp
, IMAP
);
132 st
.f_favail
= st
.f_ffree
;
134 st
.f_flag
= (sp
->s_rd_only
== 1 ? ST_RDONLY
: 0);
135 st
.f_namemax
= MFS_DIRSIZ
;
137 /* Copy the struct to user space. */
138 r
= sys_safecopyto(fs_m_in
.m_source
, fs_m_in
.REQ_GRANT
, 0, (vir_bytes
) &st
,
139 (phys_bytes
) sizeof(st
));
144 /*===========================================================================*
146 *===========================================================================*/
149 register int r
; /* return value */
150 register struct inode
*rip
; /* target inode */
152 if ((rip
= get_inode(fs_dev
, (ino_t
) fs_m_in
.REQ_INODE_NR
)) == NULL
)
155 r
= stat_inode(rip
, fs_m_in
.m_source
, (cp_grant_id_t
) fs_m_in
.REQ_GRANT
);
156 put_inode(rip
); /* release the inode */