diff options
Diffstat (limited to 'fs/jffs2')
-rw-r--r-- | fs/jffs2/acl.c | 6 | ||||
-rw-r--r-- | fs/jffs2/acl.h | 2 | ||||
-rw-r--r-- | fs/jffs2/fs.c | 6 | ||||
-rw-r--r-- | fs/jffs2/nodelist.c | 9 | ||||
-rw-r--r-- | fs/jffs2/readinode.c | 31 | ||||
-rw-r--r-- | fs/jffs2/write.c | 28 |
6 files changed, 42 insertions, 40 deletions
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 77fc5838609c..4c80404a9aba 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
@@ -176,7 +176,7 @@ static void jffs2_iset_acl(struct inode *inode, struct posix_acl **i_acl, struct | |||
176 | spin_unlock(&inode->i_lock); | 176 | spin_unlock(&inode->i_lock); |
177 | } | 177 | } |
178 | 178 | ||
179 | struct posix_acl *jffs2_get_acl(struct inode *inode, int type) | 179 | static struct posix_acl *jffs2_get_acl(struct inode *inode, int type) |
180 | { | 180 | { |
181 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); | 181 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); |
182 | struct posix_acl *acl; | 182 | struct posix_acl *acl; |
@@ -345,8 +345,10 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) | |||
345 | if (!clone) | 345 | if (!clone) |
346 | return -ENOMEM; | 346 | return -ENOMEM; |
347 | rc = posix_acl_create_masq(clone, (mode_t *)i_mode); | 347 | rc = posix_acl_create_masq(clone, (mode_t *)i_mode); |
348 | if (rc < 0) | 348 | if (rc < 0) { |
349 | posix_acl_release(clone); | ||
349 | return rc; | 350 | return rc; |
351 | } | ||
350 | if (rc > 0) | 352 | if (rc > 0) |
351 | jffs2_iset_acl(inode, &f->i_acl_access, clone); | 353 | jffs2_iset_acl(inode, &f->i_acl_access, clone); |
352 | 354 | ||
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h index 76c6ebd1acd9..0bb7f003fd80 100644 --- a/fs/jffs2/acl.h +++ b/fs/jffs2/acl.h | |||
@@ -28,7 +28,6 @@ struct jffs2_acl_header { | |||
28 | 28 | ||
29 | #define JFFS2_ACL_NOT_CACHED ((void *)-1) | 29 | #define JFFS2_ACL_NOT_CACHED ((void *)-1) |
30 | 30 | ||
31 | extern struct posix_acl *jffs2_get_acl(struct inode *inode, int type); | ||
32 | extern int jffs2_permission(struct inode *, int, struct nameidata *); | 31 | extern int jffs2_permission(struct inode *, int, struct nameidata *); |
33 | extern int jffs2_acl_chmod(struct inode *); | 32 | extern int jffs2_acl_chmod(struct inode *); |
34 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); | 33 | extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); |
@@ -40,7 +39,6 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler; | |||
40 | 39 | ||
41 | #else | 40 | #else |
42 | 41 | ||
43 | #define jffs2_get_acl(inode, type) (NULL) | ||
44 | #define jffs2_permission (NULL) | 42 | #define jffs2_permission (NULL) |
45 | #define jffs2_acl_chmod(inode) (0) | 43 | #define jffs2_acl_chmod(inode) (0) |
46 | #define jffs2_init_acl_pre(dir_i,inode,mode) (0) | 44 | #define jffs2_init_acl_pre(dir_i,inode,mode) (0) |
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 6d1eaddde0ec..e26ea78c7892 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c | |||
@@ -97,11 +97,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) | |||
97 | ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid); | 97 | ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid); |
98 | 98 | ||
99 | if (ivalid & ATTR_MODE) | 99 | if (ivalid & ATTR_MODE) |
100 | if (iattr->ia_mode & S_ISGID && | 100 | ri->mode = cpu_to_jemode(iattr->ia_mode); |
101 | !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID)) | ||
102 | ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID); | ||
103 | else | ||
104 | ri->mode = cpu_to_jemode(iattr->ia_mode); | ||
105 | else | 101 | else |
106 | ri->mode = cpu_to_jemode(inode->i_mode); | 102 | ri->mode = cpu_to_jemode(inode->i_mode); |
107 | 103 | ||
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index 4bf86088b3ae..87c6f555e1a0 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c | |||
@@ -32,15 +32,18 @@ void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new | |||
32 | if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) { | 32 | if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) { |
33 | /* Duplicate. Free one */ | 33 | /* Duplicate. Free one */ |
34 | if (new->version < (*prev)->version) { | 34 | if (new->version < (*prev)->version) { |
35 | dbg_dentlist("Eep! Marking new dirent node is obsolete, old is \"%s\", ino #%u\n", | 35 | dbg_dentlist("Eep! Marking new dirent node obsolete, old is \"%s\", ino #%u\n", |
36 | (*prev)->name, (*prev)->ino); | 36 | (*prev)->name, (*prev)->ino); |
37 | jffs2_mark_node_obsolete(c, new->raw); | 37 | jffs2_mark_node_obsolete(c, new->raw); |
38 | jffs2_free_full_dirent(new); | 38 | jffs2_free_full_dirent(new); |
39 | } else { | 39 | } else { |
40 | dbg_dentlist("marking old dirent \"%s\", ino #%u bsolete\n", | 40 | dbg_dentlist("marking old dirent \"%s\", ino #%u obsolete\n", |
41 | (*prev)->name, (*prev)->ino); | 41 | (*prev)->name, (*prev)->ino); |
42 | new->next = (*prev)->next; | 42 | new->next = (*prev)->next; |
43 | jffs2_mark_node_obsolete(c, ((*prev)->raw)); | 43 | /* It may have been a 'placeholder' deletion dirent, |
44 | if jffs2_can_mark_obsolete() (see jffs2_do_unlink()) */ | ||
45 | if ((*prev)->raw) | ||
46 | jffs2_mark_node_obsolete(c, ((*prev)->raw)); | ||
44 | jffs2_free_full_dirent(*prev); | 47 | jffs2_free_full_dirent(*prev); |
45 | *prev = new; | 48 | *prev = new; |
46 | } | 49 | } |
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 6c1ba3566f58..e512a93d6249 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -37,23 +37,24 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info | |||
37 | 37 | ||
38 | BUG_ON(tn->csize == 0); | 38 | BUG_ON(tn->csize == 0); |
39 | 39 | ||
40 | if (!jffs2_is_writebuffered(c)) | ||
41 | goto adj_acc; | ||
42 | |||
43 | /* Calculate how many bytes were already checked */ | 40 | /* Calculate how many bytes were already checked */ |
44 | ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode); | 41 | ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode); |
45 | len = ofs % c->wbuf_pagesize; | 42 | len = tn->csize; |
46 | if (likely(len)) | 43 | |
47 | len = c->wbuf_pagesize - len; | 44 | if (jffs2_is_writebuffered(c)) { |
48 | 45 | int adj = ofs % c->wbuf_pagesize; | |
49 | if (len >= tn->csize) { | 46 | if (likely(adj)) |
50 | dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n", | 47 | adj = c->wbuf_pagesize - adj; |
51 | ref_offset(ref), tn->csize, ofs); | 48 | |
52 | goto adj_acc; | 49 | if (adj >= tn->csize) { |
53 | } | 50 | dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n", |
51 | ref_offset(ref), tn->csize, ofs); | ||
52 | goto adj_acc; | ||
53 | } | ||
54 | 54 | ||
55 | ofs += len; | 55 | ofs += adj; |
56 | len = tn->csize - len; | 56 | len -= adj; |
57 | } | ||
57 | 58 | ||
58 | dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n", | 59 | dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n", |
59 | ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); | 60 | ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len); |
@@ -63,7 +64,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info | |||
63 | * adding and jffs2_flash_read_end() interface. */ | 64 | * adding and jffs2_flash_read_end() interface. */ |
64 | if (c->mtd->point) { | 65 | if (c->mtd->point) { |
65 | err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); | 66 | err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer); |
66 | if (!err && retlen < tn->csize) { | 67 | if (!err && retlen < len) { |
67 | JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); | 68 | JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize); |
68 | c->mtd->unpoint(c->mtd, buffer, ofs, retlen); | 69 | c->mtd->unpoint(c->mtd, buffer, ofs, retlen); |
69 | } else if (err) | 70 | } else if (err) |
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c index 1b88e6e734ef..776f13cbf2b5 100644 --- a/fs/jffs2/write.c +++ b/fs/jffs2/write.c | |||
@@ -582,7 +582,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
582 | jffs2_add_fd_to_list(c, fd, &dir_f->dents); | 582 | jffs2_add_fd_to_list(c, fd, &dir_f->dents); |
583 | up(&dir_f->sem); | 583 | up(&dir_f->sem); |
584 | } else { | 584 | } else { |
585 | struct jffs2_full_dirent **prev = &dir_f->dents; | 585 | struct jffs2_full_dirent *fd = dir_f->dents; |
586 | uint32_t nhash = full_name_hash(name, namelen); | 586 | uint32_t nhash = full_name_hash(name, namelen); |
587 | 587 | ||
588 | /* We don't actually want to reserve any space, but we do | 588 | /* We don't actually want to reserve any space, but we do |
@@ -590,21 +590,22 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
590 | down(&c->alloc_sem); | 590 | down(&c->alloc_sem); |
591 | down(&dir_f->sem); | 591 | down(&dir_f->sem); |
592 | 592 | ||
593 | while ((*prev) && (*prev)->nhash <= nhash) { | 593 | for (fd = dir_f->dents; fd; fd = fd->next) { |
594 | if ((*prev)->nhash == nhash && | 594 | if (fd->nhash == nhash && |
595 | !memcmp((*prev)->name, name, namelen) && | 595 | !memcmp(fd->name, name, namelen) && |
596 | !(*prev)->name[namelen]) { | 596 | !fd->name[namelen]) { |
597 | struct jffs2_full_dirent *this = *prev; | ||
598 | 597 | ||
599 | D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n", | 598 | D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n", |
600 | this->ino, ref_offset(this->raw))); | 599 | fd->ino, ref_offset(fd->raw))); |
601 | 600 | jffs2_mark_node_obsolete(c, fd->raw); | |
602 | *prev = this->next; | 601 | /* We don't want to remove it from the list immediately, |
603 | jffs2_mark_node_obsolete(c, (this->raw)); | 602 | because that screws up getdents()/seek() semantics even |
604 | jffs2_free_full_dirent(this); | 603 | more than they're screwed already. Turn it into a |
604 | node-less deletion dirent instead -- a placeholder */ | ||
605 | fd->raw = NULL; | ||
606 | fd->ino = 0; | ||
605 | break; | 607 | break; |
606 | } | 608 | } |
607 | prev = &((*prev)->next); | ||
608 | } | 609 | } |
609 | up(&dir_f->sem); | 610 | up(&dir_f->sem); |
610 | } | 611 | } |
@@ -630,7 +631,8 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, | |||
630 | D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", | 631 | D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", |
631 | fd->name, dead_f->inocache->ino)); | 632 | fd->name, dead_f->inocache->ino)); |
632 | } | 633 | } |
633 | jffs2_mark_node_obsolete(c, fd->raw); | 634 | if (fd->raw) |
635 | jffs2_mark_node_obsolete(c, fd->raw); | ||
634 | jffs2_free_full_dirent(fd); | 636 | jffs2_free_full_dirent(fd); |
635 | } | 637 | } |
636 | } | 638 | } |