1 /* This file contains file metadata retrieval and manipulation routines.
3 * The entry points into this file are:
4 * get_mode return a file's mode
5 * do_stat perform the STAT file system call
6 * do_chmod perform the CHMOD file system call
7 * do_utime perform the UTIME file system call
10 * April 2009 (D.C. van Moolenbroek)
15 /*===========================================================================*
17 *===========================================================================*/
18 mode_t
get_mode(struct inode
*ino
, int mode
)
20 /* Return the mode for an inode, given the inode and the retrieved mode.
24 mode
= mode
| (mode
>> 3) | (mode
>> 6);
27 mode
= S_IFDIR
| (mode
& sffs_params
->p_dir_mask
);
29 mode
= S_IFREG
| (mode
& sffs_params
->p_file_mask
);
32 mode
&= ~(S_IWUSR
| S_IWGRP
| S_IWOTH
);
37 /*===========================================================================*
39 *===========================================================================*/
40 int do_stat(ino_t ino_nr
, struct stat
*st
)
42 /* Retrieve inode status.
45 struct sffs_attr attr
;
49 /* Don't increase the inode refcount: it's already open anyway */
50 if ((ino
= find_inode(ino_nr
)) == NULL
)
53 attr
.a_mask
= SFFS_ATTR_MODE
| SFFS_ATTR_SIZE
| SFFS_ATTR_CRTIME
|
54 SFFS_ATTR_ATIME
| SFFS_ATTR_MTIME
| SFFS_ATTR_CTIME
;
56 if ((r
= verify_inode(ino
, path
, &attr
)) != OK
)
59 st
->st_mode
= get_mode(ino
, attr
.a_mode
);
60 st
->st_uid
= sffs_params
->p_uid
;
61 st
->st_gid
= sffs_params
->p_gid
;
63 st
->st_size
= attr
.a_size
;
64 st
->st_atimespec
= attr
.a_atime
;
65 st
->st_mtimespec
= attr
.a_mtime
;
66 st
->st_ctimespec
= attr
.a_ctime
;
67 st
->st_birthtimespec
= attr
.a_crtime
;
69 st
->st_blocks
= st
->st_size
/ S_BLKSIZE
;
70 if (st
->st_size
% S_BLKSIZE
!= 0)
73 st
->st_blksize
= BLOCK_SIZE
;
75 /* We could make this more accurate by iterating over directory inodes'
76 * children, counting how many of those are directories as well.
77 * It's just not worth it.
80 if (ino
->i_parent
!= NULL
) st
->st_nlink
++;
83 if (HAS_CHILDREN(ino
)) st
->st_nlink
++;
89 /*===========================================================================*
91 *===========================================================================*/
92 int do_chmod(ino_t ino_nr
, mode_t
*mode
)
98 struct sffs_attr attr
;
104 if ((ino
= find_inode(ino_nr
)) == NULL
)
107 if ((r
= verify_inode(ino
, path
, NULL
)) != OK
)
110 /* Set the new file mode. */
111 attr
.a_mask
= SFFS_ATTR_MODE
;
112 attr
.a_mode
= *mode
; /* no need to convert in this direction */
114 if ((r
= sffs_table
->t_setattr(path
, &attr
)) != OK
)
117 /* We have no idea what really happened. Query for the mode again. */
118 if ((r
= verify_path(path
, ino
, &attr
, NULL
)) != OK
)
121 *mode
= get_mode(ino
, attr
.a_mode
);
126 /*===========================================================================*
128 *===========================================================================*/
129 int do_utime(ino_t ino_nr
, struct timespec
*atime
, struct timespec
*mtime
)
135 struct sffs_attr attr
;
141 if ((ino
= find_inode(ino_nr
)) == NULL
)
144 if ((r
= verify_inode(ino
, path
, NULL
)) != OK
)
149 switch (atime
->tv_nsec
) {
150 case UTIME_OMIT
: /* do not touch */
153 /* XXX VFS should have time() into ACTIME, for compat; we trust it! */
157 attr
.a_atime
= *atime
;
158 attr
.a_mask
|= SFFS_ATTR_ATIME
;
162 switch (mtime
->tv_nsec
) {
163 case UTIME_OMIT
: /* do not touch */
166 /* XXX VFS should have time() into MODTIME, for compat; we trust it! */
170 attr
.a_mtime
= *mtime
;
171 attr
.a_mask
|= SFFS_ATTR_MTIME
;
175 return sffs_table
->t_setattr(path
, &attr
);