blob: a9ced27250aa0f86f4c079b8d5227b861dc61eba [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001/*
2 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3 *
4 * Copyright (C) 2002-2018 Aleph One Ltd.
5 *
6 * Created by Charles Manning <charles@aleph1.co.uk>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include "yaffs_guts.h"
14#include "yaffs_attribs.h"
15
16#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
17#define IATTR_UID ia_uid
18#define IATTR_GID ia_gid
19#else
20#define IATTR_UID ia_uid.val
21#define IATTR_GID ia_gid.val
22#endif
23
24/*
25 * Loading attibs from/to object header assumes the object header
26 * is in cpu endian.
27 */
28void yaffs_load_attribs(struct yaffs_obj *obj, struct yaffs_obj_hdr *oh)
29{
30 obj->yst_uid = oh->yst_uid;
31 obj->yst_gid = oh->yst_gid;
32 obj->yst_atime = oh->yst_atime;
33 obj->yst_mtime = oh->yst_mtime;
34 obj->yst_ctime = oh->yst_ctime;
35 obj->yst_rdev = oh->yst_rdev;
36}
37
38void yaffs_load_attribs_oh(struct yaffs_obj_hdr *oh, struct yaffs_obj *obj)
39{
40 oh->yst_uid = obj->yst_uid;
41 oh->yst_gid = obj->yst_gid;
42 oh->yst_atime = obj->yst_atime;
43 oh->yst_mtime = obj->yst_mtime;
44 oh->yst_ctime = obj->yst_ctime;
45 oh->yst_rdev = obj->yst_rdev;
46
47}
48
49void yaffs_load_current_time(struct yaffs_obj *obj, int do_a, int do_c)
50{
51 obj->yst_mtime = Y_CURRENT_TIME;
52 if (do_a)
53 obj->yst_atime = obj->yst_mtime;
54 if (do_c)
55 obj->yst_ctime = obj->yst_mtime;
56}
57
58void yaffs_attribs_init(struct yaffs_obj *obj, u32 gid, u32 uid, u32 rdev)
59{
60 yaffs_load_current_time(obj, 1, 1);
61 obj->yst_rdev = rdev;
62 obj->yst_uid = uid;
63 obj->yst_gid = gid;
64}
65
66static loff_t yaffs_get_file_size(struct yaffs_obj *obj)
67{
68 YCHAR *alias = NULL;
69 obj = yaffs_get_equivalent_obj(obj);
70
71 switch (obj->variant_type) {
72 case YAFFS_OBJECT_TYPE_FILE:
73 return obj->variant.file_variant.file_size;
74 case YAFFS_OBJECT_TYPE_SYMLINK:
75 alias = obj->variant.symlink_variant.alias;
76 if (!alias)
77 return 0;
78 return strnlen(alias, YAFFS_MAX_ALIAS_LENGTH);
79 default:
80 return 0;
81 }
82}
83
84int yaffs_set_attribs(struct yaffs_obj *obj, struct iattr *attr)
85{
86 unsigned int valid = attr->ia_valid;
87
88 if (valid & ATTR_MODE)
89 obj->yst_mode = attr->ia_mode;
90 if (valid & ATTR_UID)
91 obj->yst_uid = attr->IATTR_UID;
92 if (valid & ATTR_GID)
93 obj->yst_gid = attr->IATTR_GID;
94
95 if (valid & ATTR_ATIME)
96 obj->yst_atime = Y_TIME_CONVERT(attr->ia_atime);
97 if (valid & ATTR_CTIME)
98 obj->yst_ctime = Y_TIME_CONVERT(attr->ia_ctime);
99 if (valid & ATTR_MTIME)
100 obj->yst_mtime = Y_TIME_CONVERT(attr->ia_mtime);
101
102 if (valid & ATTR_SIZE)
103 yaffs_resize_file(obj, attr->ia_size);
104
105 yaffs_update_oh(obj, NULL, 1, 0, 0, NULL);
106
107 return YAFFS_OK;
108
109}
110
111int yaffs_get_attribs(struct yaffs_obj *obj, struct iattr *attr)
112{
113 unsigned int valid = 0;
114
115 attr->ia_mode = obj->yst_mode;
116 valid |= ATTR_MODE;
117 attr->IATTR_UID = obj->yst_uid;
118 valid |= ATTR_UID;
119 attr->IATTR_GID = obj->yst_gid;
120 valid |= ATTR_GID;
121
122 Y_TIME_CONVERT(attr->ia_atime) = obj->yst_atime;
123 valid |= ATTR_ATIME;
124 Y_TIME_CONVERT(attr->ia_ctime) = obj->yst_ctime;
125 valid |= ATTR_CTIME;
126 Y_TIME_CONVERT(attr->ia_mtime) = obj->yst_mtime;
127 valid |= ATTR_MTIME;
128
129 attr->ia_size = yaffs_get_file_size(obj);
130 valid |= ATTR_SIZE;
131
132 attr->ia_valid = valid;
133
134 return YAFFS_OK;
135}