1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
/*
Copyright (c) 2013 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
This file is licensed to you under your choice of the GNU Lesser
General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all
cases as published by the Free Software Foundation.
*/
#ifndef __GFID_ACCESS_H__
#define __GFID_ACCESS_H__
#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif
#include "glusterfs.h"
#include "logging.h"
#include "dict.h"
#include "xlator.h"
#include "defaults.h"
#include "gfid-access-mem-types.h"
#define UUID_CANONICAL_FORM_LEN 36
#define GF_FUSE_AUX_GFID_NEWFILE "glusterfs.gfid.newfile"
#define GF_FUSE_AUX_GFID_HEAL "glusterfs.gfid.heal"
#define GF_GFID_KEY "GLUSTERFS_GFID"
#define GF_GFID_DIR ".gfid"
#define GF_AUX_GFID 0xd
#define GFID_ACCESS_GET_VALID_DIR_INODE(x,l,unref,lbl) do { \
int ret = 0; \
uint64_t value = 0; \
inode_t *tmp_inode = NULL; \
\
/* if its an entry operation, on the virtual */ \
/* directory inode as parent, we need to handle */ \
/* it properly */ \
if (l->parent) { \
ret = inode_ctx_get (l->parent, x, &value); \
if (ret) \
goto lbl; \
tmp_inode = (inode_t *)value; \
unref = inode_ref (tmp_inode); \
l->parent = tmp_inode; \
/* if parent is virtual, no need to handle */ \
/* loc->inode */ \
break; \
} \
\
/* if its an inode operation, on the virtual */ \
/* directory inode itself, we need to handle */ \
/* it properly */ \
if (l->inode) { \
ret = inode_ctx_get (l->inode, x, &value); \
if (ret) \
goto lbl; \
tmp_inode = (inode_t *)value; \
unref = inode_ref (tmp_inode); \
l->inode = tmp_inode; \
} \
\
} while (0)
#define GFID_ACCESS_ENTRY_OP_CHECK(loc,err,lbl) do { \
/* need to check if the lookup is on virtual dir */ \
if ((loc->name && !strcmp (GF_GFID_DIR, loc->name)) && \
((loc->parent && \
__is_root_gfid (loc->parent->gfid)) || \
__is_root_gfid (loc->pargfid))) { \
err = EEXIST; \
goto lbl; \
} \
\
/* now, check if the lookup() is on an existing */ \
/* entry, but on gfid-path */ \
if ((loc->parent && \
__is_gfid_access_dir (loc->parent->gfid)) || \
__is_gfid_access_dir (loc->pargfid)) { \
err = EPERM; \
goto lbl; \
} \
} while (0)
typedef struct {
unsigned int uid;
unsigned int gid;
char gfid[UUID_CANONICAL_FORM_LEN + 1];
unsigned int st_mode;
char *bname;
union {
struct _symlink_in {
char *linkpath;
} __attribute__ ((__packed__)) symlink;
struct _mknod_in {
unsigned int mode;
unsigned int rdev;
unsigned int umask;
} __attribute__ ((__packed__)) mknod;
struct _mkdir_in {
unsigned int mode;
unsigned int umask;
} __attribute__ ((__packed__)) mkdir;
} __attribute__ ((__packed__)) args;
} __attribute__((__packed__)) ga_newfile_args_t;
typedef struct {
char gfid[UUID_CANONICAL_FORM_LEN + 1];
char *bname; /* a null terminated basename */
} __attribute__((__packed__)) ga_heal_args_t;
struct ga_private {
/* root inode's stbuf */
struct iatt root_stbuf;
struct iatt gfiddir_stbuf;
struct mem_pool *newfile_args_pool;
struct mem_pool *heal_args_pool;
};
typedef struct ga_private ga_private_t;
struct __ga_local {
call_frame_t *orig_frame;
unsigned int uid;
unsigned int gid;
loc_t loc;
};
typedef struct __ga_local ga_local_t;
#endif /* __GFID_ACCESS_H__ */
|