1 /**
2  * Copyright (c) 2008-2015 Alper Akcan <alper.akcan@gmail.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program (in the main directory of the fuse-ext2
16  * distribution in the file COPYING); if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #ifndef FUSEEXT2_H_
21 #define FUSEEXT2_H_
22 
23 #include <config.h>
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include <getopt.h>
30 #include <assert.h>
31 #include <dirent.h>
32 #include <errno.h>
33 #ifdef MAJOR_IN_SYSMACROS
34 #    include <sys/sysmacros.h>
35 #endif
36 
37 #include <fuse.h>
38 #include <ext2fs/ext2fs.h>
39 
40 #if !defined(FUSE_VERSION) || (FUSE_VERSION < 26)
41 #error "***********************************************************"
42 #error "*                                                         *"
43 #error "*     Compilation requires at least FUSE version 2.6.0!   *"
44 #error "*                                                         *"
45 #error "***********************************************************"
46 #endif
47 
48 /* extra definitions not yet included in ext2fs.h */
49 #define EXT2_FILE_SHARED_INODE 0x8000
50 errcode_t ext2fs_file_close2(ext2_file_t file, void (*close_callback) (struct ext2_inode *inode, int flags));
51 
52 #ifndef PATH_MAX
53 #define PATH_MAX 4096
54 #endif
55 
56 #define EXT2FS_FILE(efile) ((void *) (unsigned long) (efile))
57 /* max timeout to flush bitmaps, to reduce inconsistencies */
58 #define FLUSH_BITMAPS_TIMEOUT 10
59 
60 struct extfs_data {
61 	unsigned char debug;
62 	unsigned char silent;
63 	unsigned char force;
64 	unsigned char readonly;
65 	time_t last_flush;
66 	char *mnt_point;
67 	char *options;
68 	char *device;
69 	char *volname;
70 	ext2_filsys e2fs;
71 };
72 
current_ext2fs(void)73 static inline ext2_filsys current_ext2fs(void)
74 {
75 	struct fuse_context *mycontext=fuse_get_context();
76 	struct extfs_data *e2data=mycontext->private_data;
77 	time_t now=time(NULL);
78 	if ((now - e2data->last_flush) > FLUSH_BITMAPS_TIMEOUT) {
79 		ext2fs_write_bitmaps(e2data->e2fs);
80 		e2data->last_flush=now;
81 	}
82 	return (ext2_filsys) e2data->e2fs;
83 }
84 
ext2_read_uid(struct ext2_inode * inode)85 static inline uid_t ext2_read_uid(struct ext2_inode *inode)
86 {
87 	return ((uid_t)inode->osd2.linux2.l_i_uid_high << 16) | inode->i_uid;
88 }
89 
ext2_write_uid(struct ext2_inode * inode,uid_t uid)90 static inline void ext2_write_uid(struct ext2_inode *inode, uid_t uid)
91 {
92 	inode->i_uid = uid & 0xffff;
93 	inode->osd2.linux2.l_i_uid_high = (uid >> 16) & 0xffff;
94 }
95 
ext2_read_gid(struct ext2_inode * inode)96 static inline gid_t ext2_read_gid(struct ext2_inode *inode)
97 {
98 	return ((gid_t)inode->osd2.linux2.l_i_gid_high << 16) | inode->i_gid;
99 }
100 
ext2_write_gid(struct ext2_inode * inode,gid_t gid)101 static inline void ext2_write_gid(struct ext2_inode *inode, gid_t gid)
102 {
103 	inode->i_gid = gid & 0xffff;
104 	inode->osd2.linux2.l_i_gid_high = (gid >> 16) & 0xffff;
105 }
106 
107 #if ENABLE_DEBUG
108 
debug_printf(const char * function,char * file,int line,const char * fmt,...)109 static inline void debug_printf (const char *function, char *file, int line, const char *fmt, ...)
110 {
111 	va_list args;
112 	struct fuse_context *mycontext=fuse_get_context();
113 	struct extfs_data *e2data=mycontext->private_data;
114 	if (e2data && (e2data->debug == 0 || e2data->silent == 1)) {
115 		return;
116 	}
117 	printf("%s: ", PACKAGE);
118 	va_start(args, fmt);
119 	vprintf(fmt, args);
120 	va_end(args);
121 	printf(" [%s (%s:%d)]\n", function, file, line);
122 }
123 
124 #define debugf(a...) { \
125 	debug_printf(__FUNCTION__, __FILE__, __LINE__, a); \
126 }
127 
debug_main_printf(const char * function,char * file,int line,const char * fmt,...)128 static inline void debug_main_printf (const char *function, char *file, int line, const char *fmt, ...)
129 {
130 	va_list args;
131 	printf("%s: ", PACKAGE);
132 	va_start(args, fmt);
133 	vprintf(fmt, args);
134 	va_end(args);
135 	printf(" [%s (%s:%d)]\n", function, file, line);
136 }
137 
138 #define debugf_main(a...) { \
139 	debug_main_printf(__FUNCTION__, __FILE__, __LINE__, a); \
140 }
141 
142 #else /* ENABLE_DEBUG */
143 
144 #define debugf(a...) do { } while(0)
145 #define debugf_main(a...) do { } while(0)
146 
147 #endif /* ENABLE_DEBUG */
148 
149 void * op_init (struct fuse_conn_info *conn);
150 
151 void op_destroy (void *userdata);
152 
153 /* helper functions */
154 
155 int do_probe (struct extfs_data *opts);
156 
157 int do_label (void);
158 
159 int do_check (const char *path);
160 
161 int do_check_split(const char *path, char **dirname,char **basename);
162 
163 void free_split(char *dirname, char *basename);
164 
165 void do_fillstatbuf (ext2_filsys e2fs, ext2_ino_t ino, struct ext2_inode *inode, struct stat *st);
166 
167 int do_readinode (ext2_filsys e2fs, const char *path, ext2_ino_t *ino, struct ext2_inode *inode);
168 
169 int do_writeinode (ext2_filsys e2fs, ext2_ino_t ino, struct ext2_inode *inode);
170 
171 int do_killfilebyinode (ext2_filsys e2fs, ext2_ino_t ino, struct ext2_inode *inode);
172 
173 /* read support */
174 
175 int op_access (const char *path, int mask);
176 
177 int op_fgetattr (const char *path, struct stat *stbuf, struct fuse_file_info *fi);
178 
179 int op_getattr (const char *path, struct stat *stbuf);
180 
181 int op_getxattr(const char *path, const char *name, char *value, size_t size);
182 
183 ext2_file_t do_open (ext2_filsys e2fs, const char *path, int flags);
184 
185 int op_open (const char *path, struct fuse_file_info *fi);
186 
187 int op_read (const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi);
188 
189 int op_readdir (const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi);
190 
191 int op_readlink (const char *path, char *buf, size_t size);
192 
193 int do_release (ext2_file_t efile);
194 
195 int op_release (const char *path, struct fuse_file_info *fi);
196 
197 int op_statfs(const char *path, struct statvfs *buf);
198 
199 /* write support */
200 
201 int do_modetoext2lag (mode_t mode);
202 
203 int op_chmod (const char *path, mode_t mode);
204 
205 int op_chown (const char *path, uid_t uid, gid_t gid);
206 
207 int do_create (ext2_filsys e2fs, const char *path, mode_t mode, dev_t dev, const char *fastsymlink);
208 
209 int op_create (const char *path, mode_t mode, struct fuse_file_info *fi);
210 
211 int op_flush (const char *path, struct fuse_file_info *fi);
212 
213 int op_fsync (const char *path, int datasync, struct fuse_file_info *fi);
214 
215 int op_mkdir (const char *path, mode_t mode);
216 
217 int do_check_empty_dir(ext2_filsys e2fs, ext2_ino_t ino);
218 
219 int op_rmdir (const char *path);
220 
221 int op_unlink (const char *path);
222 
223 int op_utimens (const char *path, const struct timespec tv[2]);
224 
225 size_t do_write (ext2_file_t efile, const char *buf, size_t size, off_t offset);
226 
227 int op_write (const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi);
228 
229 int op_mknod (const char *path, mode_t mode, dev_t dev);
230 
231 int op_symlink (const char *sourcename, const char *destname);
232 
233 int op_truncate(const char *path, off_t length);
234 
235 int op_ftruncate(const char *path, off_t length, struct fuse_file_info *fi);
236 
237 int op_link (const char *source, const char *dest);
238 
239 int op_rename (const char *source, const char *dest);
240 
241 #endif /* FUSEEXT2_H_ */
242