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