int f2fs_acl_chmod(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb); struct posix_acl *acl, *clone; int error; mode_t mode = get_inode_mode(inode); if (!test_opt(sbi, POSIX_ACL)) return 0; if (S_ISLNK(mode)) return -EOPNOTSUPP; acl = f2fs_get_acl(inode, ACL_TYPE_ACCESS); if (IS_ERR(acl) || !acl) return PTR_ERR(acl); //error = posix_acl_chmod(&acl, GFP_KERNEL, mode); clone = posix_acl_clone(acl, GFP_KERNEL); posix_acl_release(acl); if (!clone) return -ENOMEM; error = posix_acl_chmod_masq(clone, inode->i_mode); if (error) return error; error = f2fs_set_acl(inode, ACL_TYPE_ACCESS, acl); posix_acl_release(acl); return error; }
int f2fs_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = d_inode(dentry); struct f2fs_inode_info *fi = F2FS_I(inode); int err; err = inode_change_ok(inode, attr); if (err) return err; if (attr->ia_valid & ATTR_SIZE) { if (f2fs_encrypted_inode(inode) && fscrypt_get_encryption_info(inode)) return -EACCES; if (attr->ia_size <= i_size_read(inode)) { truncate_setsize(inode, attr->ia_size); err = f2fs_truncate(inode, true); if (err) return err; f2fs_balance_fs(F2FS_I_SB(inode), true); } else { /* * do not trim all blocks after i_size if target size is * larger than i_size. */ truncate_setsize(inode, attr->ia_size); /* should convert inline inode here */ if (!f2fs_may_inline_data(inode)) { err = f2fs_convert_inline_inode(inode); if (err) return err; } inode->i_mtime = inode->i_ctime = CURRENT_TIME; } } __setattr_copy(inode, attr); if (attr->ia_valid & ATTR_MODE) { err = posix_acl_chmod(inode, get_inode_mode(inode)); if (err || is_inode_flag_set(fi, FI_ACL_MODE)) { inode->i_mode = fi->i_acl_mode; clear_inode_flag(fi, FI_ACL_MODE); } } mark_inode_dirty(inode); return err; }
static struct inode *iso_get_inode(struct fs_info *fs, const struct iso_dir_entry *de) { struct inode *inode = new_iso_inode(fs); int blktosec = BLOCK_SHIFT(fs) - SECTOR_SHIFT(fs); if (!inode) return NULL; dprintf("Getting inode for: %.*s\n", de->name_len, de->name); inode->mode = get_inode_mode(de->flags); inode->size = de->size_le; PVT(inode)->lba = de->extent_le; inode->blocks = (inode->size + BLOCK_SIZE(fs) - 1) >> BLOCK_SHIFT(fs); /* We have a single extent for all data */ inode->next_extent.pstart = (sector_t)de->extent_le << blktosec; inode->next_extent.len = (sector_t)inode->blocks << blktosec; return inode; }
data = get_cache(fs->fs_dev, PVT(inode)->lba + i); } de = (const struct iso_dir_entry *)(data + offset); if (de->length < 33 || offset + de->length > BLOCK_SIZE(fs)) { file->offset = (file->offset + BLOCK_SIZE(fs)) & ~(BLOCK_SIZE(fs) - 1); /* Start of the next block */ data = NULL; continue; } break; } dirent->d_ino = 0; /* Inode number is invalid to ISO fs */ dirent->d_off = file->offset; dirent->d_type = get_inode_mode(de->flags); /* Try to get Rock Ridge name */ ret = susp_rr_get_nm(fs, (char *) de, &rr_name, &name_len); if (ret > 0) { memcpy(dirent->d_name, rr_name, name_len + 1); free(rr_name); rr_name = NULL; } else { name_len = iso_convert_name(dirent->d_name, de->name, de->name_len); } dirent->d_reclen = offsetof(struct dirent, d_name) + 1 + name_len; file->offset += de->length; /* Update for next reading */