1 /* VTreeFS - stadir.c - file and file system status management */ 2 3 #include "inc.h" 4 5 /* 6 * Retrieve file status. 7 */ 8 int 9 fs_stat(ino_t ino_nr, struct stat * buf) 10 { 11 char path[PATH_MAX]; 12 time_t cur_time; 13 struct inode *node; 14 int r; 15 16 if ((node = find_inode(ino_nr)) == NULL) 17 return EINVAL; 18 19 /* Fill in the basic info. */ 20 buf->st_ino = get_inode_number(node); 21 buf->st_mode = node->i_stat.mode; 22 buf->st_nlink = !is_inode_deleted(node); 23 buf->st_uid = node->i_stat.uid; 24 buf->st_gid = node->i_stat.gid; 25 buf->st_rdev = (dev_t) node->i_stat.dev; 26 buf->st_size = node->i_stat.size; 27 28 /* If it is a symbolic link, return the size of the link target. */ 29 if (S_ISLNK(node->i_stat.mode) && vtreefs_hooks->rdlink_hook != NULL) { 30 r = vtreefs_hooks->rdlink_hook(node, path, sizeof(path), 31 get_inode_cbdata(node)); 32 33 if (r == OK) 34 buf->st_size = strlen(path); 35 } 36 37 /* Take the current time as file time for all files. */ 38 cur_time = clock_time(NULL); 39 buf->st_atime = cur_time; 40 buf->st_mtime = cur_time; 41 buf->st_ctime = cur_time; 42 43 return OK; 44 } 45 46 /* 47 * Change file mode. 48 */ 49 int 50 fs_chmod(ino_t ino_nr, mode_t * mode) 51 { 52 struct inode *node; 53 struct inode_stat stat; 54 int r; 55 56 if ((node = find_inode(ino_nr)) == NULL) 57 return EINVAL; 58 59 if (vtreefs_hooks->chstat_hook == NULL) 60 return ENOSYS; 61 62 get_inode_stat(node, &stat); 63 64 stat.mode = (stat.mode & ~ALL_MODES) | (*mode & ALL_MODES); 65 66 r = vtreefs_hooks->chstat_hook(node, &stat, get_inode_cbdata(node)); 67 68 if (r != OK) 69 return r; 70 71 get_inode_stat(node, &stat); 72 73 *mode = stat.mode; 74 75 return OK; 76 } 77 78 /* 79 * Change file ownership. 80 */ 81 int 82 fs_chown(ino_t ino_nr, uid_t uid, gid_t gid, mode_t * mode) 83 { 84 struct inode *node; 85 struct inode_stat stat; 86 int r; 87 88 if ((node = find_inode(ino_nr)) == NULL) 89 return EINVAL; 90 91 if (vtreefs_hooks->chstat_hook == NULL) 92 return ENOSYS; 93 94 get_inode_stat(node, &stat); 95 96 stat.uid = uid; 97 stat.gid = gid; 98 stat.mode &= ~(S_ISUID | S_ISGID); 99 100 r = vtreefs_hooks->chstat_hook(node, &stat, get_inode_cbdata(node)); 101 102 if (r != OK) 103 return r; 104 105 get_inode_stat(node, &stat); 106 107 *mode = stat.mode; 108 109 return OK; 110 } 111 112 /* 113 * Retrieve file system statistics. 114 */ 115 int 116 fs_statvfs(struct statvfs * buf) 117 { 118 119 buf->f_flag = ST_NOTRUNC; 120 buf->f_namemax = PNAME_MAX; 121 122 return OK; 123 } 124