Merge "sdcard : inode numbers must be fully representable as uint32_t." into lmp-mr1-dev
This commit is contained in:
commit
0f86444b39
1 changed files with 34 additions and 1 deletions
|
|
@ -168,6 +168,11 @@ struct node {
|
||||||
__u32 refcount;
|
__u32 refcount;
|
||||||
__u64 nid;
|
__u64 nid;
|
||||||
__u64 gen;
|
__u64 gen;
|
||||||
|
/*
|
||||||
|
* The inode number for this FUSE node. Note that this isn't stable across
|
||||||
|
* multiple invocations of the FUSE daemon.
|
||||||
|
*/
|
||||||
|
__u32 ino;
|
||||||
|
|
||||||
/* State derived based on current position in hierarchy. */
|
/* State derived based on current position in hierarchy. */
|
||||||
perm_t perm;
|
perm_t perm;
|
||||||
|
|
@ -224,6 +229,25 @@ struct fuse {
|
||||||
struct node root;
|
struct node root;
|
||||||
char obbpath[PATH_MAX];
|
char obbpath[PATH_MAX];
|
||||||
|
|
||||||
|
/* Used to allocate unique inode numbers for fuse nodes. We use
|
||||||
|
* a simple counter based scheme where inode numbers from deleted
|
||||||
|
* nodes aren't reused. Note that inode allocations are not stable
|
||||||
|
* across multiple invocation of the sdcard daemon, but that shouldn't
|
||||||
|
* be a huge problem in practice.
|
||||||
|
*
|
||||||
|
* Note that we restrict inodes to 32 bit unsigned integers to prevent
|
||||||
|
* truncation on 32 bit processes when unsigned long long stat.st_ino is
|
||||||
|
* assigned to an unsigned long ino_t type in an LP32 process.
|
||||||
|
*
|
||||||
|
* Also note that fuse_attr and fuse_dirent inode values are 64 bits wide
|
||||||
|
* on both LP32 and LP64, but the fuse kernel code doesn't squash 64 bit
|
||||||
|
* inode numbers into 32 bit values on 64 bit kernels (see fuse_squash_ino
|
||||||
|
* in fs/fuse/inode.c).
|
||||||
|
*
|
||||||
|
* Accesses must be guarded by |lock|.
|
||||||
|
*/
|
||||||
|
__u32 inode_ctr;
|
||||||
|
|
||||||
Hashmap* package_to_appid;
|
Hashmap* package_to_appid;
|
||||||
Hashmap* appid_with_rw;
|
Hashmap* appid_with_rw;
|
||||||
};
|
};
|
||||||
|
|
@ -387,7 +411,7 @@ static char* find_file_within(const char* path, const char* name,
|
||||||
|
|
||||||
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
|
static void attr_from_stat(struct fuse_attr *attr, const struct stat *s, const struct node* node)
|
||||||
{
|
{
|
||||||
attr->ino = node->nid;
|
attr->ino = node->ino;
|
||||||
attr->size = s->st_size;
|
attr->size = s->st_size;
|
||||||
attr->blocks = s->st_blocks;
|
attr->blocks = s->st_blocks;
|
||||||
attr->atime = s->st_atime;
|
attr->atime = s->st_atime;
|
||||||
|
|
@ -575,6 +599,13 @@ struct node *create_node_locked(struct fuse* fuse,
|
||||||
struct node *node;
|
struct node *node;
|
||||||
size_t namelen = strlen(name);
|
size_t namelen = strlen(name);
|
||||||
|
|
||||||
|
// Detect overflows in the inode counter. "4 billion nodes should be enough
|
||||||
|
// for everybody".
|
||||||
|
if (fuse->inode_ctr == 0) {
|
||||||
|
ERROR("No more inode numbers available");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
node = calloc(1, sizeof(struct node));
|
node = calloc(1, sizeof(struct node));
|
||||||
if (!node) {
|
if (!node) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -596,6 +627,7 @@ struct node *create_node_locked(struct fuse* fuse,
|
||||||
}
|
}
|
||||||
node->namelen = namelen;
|
node->namelen = namelen;
|
||||||
node->nid = ptr_to_id(node);
|
node->nid = ptr_to_id(node);
|
||||||
|
node->ino = fuse->inode_ctr++;
|
||||||
node->gen = fuse->next_generation++;
|
node->gen = fuse->next_generation++;
|
||||||
|
|
||||||
derive_permissions_locked(fuse, parent, node);
|
derive_permissions_locked(fuse, parent, node);
|
||||||
|
|
@ -700,6 +732,7 @@ static void fuse_init(struct fuse *fuse, int fd, const char *source_path,
|
||||||
fuse->derive = derive;
|
fuse->derive = derive;
|
||||||
fuse->split_perms = split_perms;
|
fuse->split_perms = split_perms;
|
||||||
fuse->write_gid = write_gid;
|
fuse->write_gid = write_gid;
|
||||||
|
fuse->inode_ctr = 1;
|
||||||
|
|
||||||
memset(&fuse->root, 0, sizeof(fuse->root));
|
memset(&fuse->root, 0, sizeof(fuse->root));
|
||||||
fuse->root.nid = FUSE_ROOT_ID; /* 1 */
|
fuse->root.nid = FUSE_ROOT_ID; /* 1 */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue