diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-04 07:40:19 +0000 |
commit | 33263fc5f9ac8e8cb2b22d06af3ce5ac1dd815e4 (patch) | |
tree | 2d1b86a40bef0958a68cf1a2eafbeb0667a70543 /fs/hpfs | |
parent | 216f5f51aa02f8b113aa620ebc14a9631a217a00 (diff) |
Merge with Linux 2.3.32.
Diffstat (limited to 'fs/hpfs')
-rw-r--r-- | fs/hpfs/ea.c | 58 | ||||
-rw-r--r-- | fs/hpfs/file.c | 48 | ||||
-rw-r--r-- | fs/hpfs/hpfs_fn.h | 8 | ||||
-rw-r--r-- | fs/hpfs/inode.c | 30 | ||||
-rw-r--r-- | fs/hpfs/namei.c | 61 |
5 files changed, 92 insertions, 113 deletions
diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c index d7abdc991..9632c054c 100644 --- a/fs/hpfs/ea.c +++ b/fs/hpfs/ea.c @@ -69,8 +69,64 @@ static void set_indirect_ea(struct super_block *s, int ano, secno a, char *data, hpfs_ea_write(s, a, ano, 0, size, data); } -/* Read an extended attribute named 'key' */ +/* Read an extended attribute named 'key' into the provided buffer */ +int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key, + char *buf, int size) +{ + unsigned pos; + int ano, len; + secno a; + struct extended_attribute *ea; + struct extended_attribute *ea_end = fnode_end_ea(fnode); + for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea)) + if (!strcmp(ea->name, key)) { + if (ea->indirect) + goto indirect; + if (ea->valuelen >= size) + return -EINVAL; + memcpy(buf, ea_data(ea), ea->valuelen); + buf[ea->valuelen] = 0; + return 0; + } + a = fnode->ea_secno; + len = fnode->ea_size_l; + ano = fnode->ea_anode; + pos = 0; + while (pos < len) { + char ex[4 + 255 + 1 + 8]; + ea = (struct extended_attribute *)ex; + if (pos + 4 > len) { + hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x", + ano ? "anode" : "sectors", a, len); + return -EIO; + } + if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO; + if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4)) + return -EIO; + if (!strcmp(ea->name, key)) { + if (ea->indirect) + goto indirect; + if (ea->valuelen >= size) + return -EINVAL; + if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, buf)) + return -EIO; + buf[ea->valuelen] = 0; + return 0; + } + pos += ea->namelen + ea->valuelen + 5; + } + return -ENOENT; +indirect: + if (ea_len(ea) >= size) + return -EINVAL; + if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 0, ea_len(ea), buf)) + return -EIO; + buf[ea_len(ea)] = 0; + return 0; +} + +/* Read an extended attribute named 'key' */ char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size) { char *ret; diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 72f61c20a..8abaf2fd3 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c @@ -89,55 +89,25 @@ static int hpfs_write_partial_page(struct file *file, struct page *page, unsigne { struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; - struct page *new_page, **hash; + struct page *new_page; unsigned long pgpos; - struct page * page_cache = NULL; long status; - printk("- off: %08x\n", (int)page->offset); - pgpos = (inode->i_blocks - 1) * 512 & PAGE_CACHE_MASK; - while (pgpos < page->offset) { -long pgp = pgpos; - printk("pgpos: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks); - hash = page_hash(&inode->i_data, pgpos); -repeat_find: new_page = __find_lock_page(&inode->i_data, pgpos, hash); - if (!new_page) { - if (!page_cache) { - page_cache = page_cache_alloc(); - if (page_cache) - goto repeat_find; - status = -ENOMEM; - goto out; - } - new_page = page_cache; - if (add_to_page_cache_unique(new_page,&inode->i_data,pgpos,hash)) - goto repeat_find; - page_cache = NULL; - } - printk("A\n"); + pgpos = ((inode->i_blocks - 1) * 512) >> PAGE_CACHE_SHIFT; + while (pgpos < page->index) { + status = -ENOMEM; + new_page = grab_cache_page(&inode->i_data, pgpos); + if (!new_page) + goto out; status = block_write_cont_page(file, new_page, PAGE_SIZE, 0, NULL); - printk("B\n"); UnlockPage(new_page); page_cache_release(new_page); if (status < 0) goto out; - pgpos = (inode->i_blocks - 1) * 512 & PAGE_CACHE_MASK; - printk("pgpos2: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks); - if (pgpos == pgp) { - status = -1; - printk("ERROR\n"); - goto out; - } + pgpos = ((inode->i_blocks - 1) * 512) >> PAGE_CACHE_SHIFT; } - //if ((status = block_write_cont_page(file, page, PAGE_SIZE, 0, NULL)) < 0) goto out; - printk("C\n"); status = block_write_cont_page(file, page, offset, bytes, buf); - printk("D\n"); out: - printk("O\n"); - if (page_cache) - page_cache_free(page_cache); - printk("E\n"); return status; } @@ -147,7 +117,7 @@ ssize_t hpfs_file_write(struct file *file, const char *buf, size_t count, loff_t ssize_t retval; retval = generic_file_write(file, buf, count, - ppos, /*hpfs_write_partial_page*/block_write_partial_page); + ppos, hpfs_write_partial_page); if (retval > 0) { struct inode *inode = file->f_dentry->d_inode; inode->i_mtime = CURRENT_TIME; diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 9ae4a67da..377b296e8 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -249,6 +249,7 @@ struct hpfs_dirent *map_fnode_dirent(struct super_block *, fnode_secno, struct f /* ea.c */ void hpfs_ea_ext_remove(struct super_block *, secno, int, unsigned); +int hpfs_read_ea(struct super_block *, struct fnode *, char *, char *, int); char *hpfs_get_ea(struct super_block *, struct fnode *, char *, int *); void hpfs_set_ea(struct inode *, struct fnode *, char *, char *, int); @@ -283,10 +284,6 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_h struct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *); dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino); -/* mmap.c */ - -int hpfs_mmap(struct file *, struct vm_area_struct *); - /* name.c */ unsigned char hpfs_upcase(unsigned char *, unsigned char); @@ -305,8 +302,7 @@ int hpfs_mknod(struct inode *, struct dentry *, int, int); int hpfs_symlink(struct inode *, struct dentry *, const char *); int hpfs_unlink(struct inode *, struct dentry *); int hpfs_rmdir(struct inode *, struct dentry *); -int hpfs_readlink(struct dentry *, char *, int); -struct dentry *hpfs_follow_link(struct dentry *, struct dentry *, unsigned int); +int hpfs_symlink_readpage(struct dentry *, struct page *); int hpfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); /* super.c */ diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index d79e55814..e4167bfdc 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c @@ -16,7 +16,7 @@ static const struct file_operations hpfs_file_ops = NULL, /* readdir - bad */ NULL, /* poll - default */ NULL, /* ioctl - default */ - generic_file_mmap/*hpfs_mmap*/, /* mmap */ + generic_file_mmap, /* mmap */ hpfs_open, /* open */ NULL, /* flush */ hpfs_file_release, /* release */ @@ -44,10 +44,8 @@ static const struct inode_operations hpfs_file_iops = &hpfs_get_block, /* get_block */ block_read_full_page, /* readpage */ block_write_full_page, /* writepage */ - block_flushpage, /* flushpage */ hpfs_truncate, /* truncate */ NULL, /* permission */ - NULL, /* smap */ NULL, /* revalidate */ }; @@ -87,38 +85,18 @@ static const struct inode_operations hpfs_dir_iops = NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ - NULL, /* flushpage */ NULL, /* truncate */ NULL, /* permission */ - NULL, /* smap */ NULL /* revalidate */ }; const struct inode_operations hpfs_symlink_iops = { - NULL, /* default file operations */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - hpfs_readlink, /* readlink */ - hpfs_follow_link, /* follow_link */ - NULL, /* get_block */ - NULL, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ + readlink: page_readlink, + follow_link: page_follow_link, + readpage: hpfs_symlink_readpage }; - void hpfs_read_inode(struct inode *i) { struct buffer_head *bh; diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index fe9b66e3d..85ce143db 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -396,54 +396,33 @@ int hpfs_rmdir(struct inode *dir, struct dentry *dentry) return r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0; } -int hpfs_readlink(struct dentry *dentry, char *buf, int len) +int hpfs_symlink_readpage(struct dentry *dentry, struct page *page) { + char *link = (char*)kmap(page); struct inode *i = dentry->d_inode; struct fnode *fnode; struct buffer_head *bh; - char *symlink; - int slen; - if (!S_ISLNK(i->i_mode)) { - return -EINVAL; - } - if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) { - return -EIO; - } - if (!(symlink = hpfs_get_ea(i->i_sb, fnode, "SYMLINK", &slen))) { - brelse(bh); - return -EFSERROR; - } - brelse(bh); - if (slen > len) slen = len; - memcpy_tofs(buf, symlink, slen); - kfree(symlink); - return slen; -} + int err; -struct dentry *hpfs_follow_link(struct dentry *dinode, struct dentry *ddir, - unsigned int follow) -{ - struct inode *inode = dinode->d_inode; - char *link; - unsigned len; - struct buffer_head *bh; - struct fnode *fnode; - if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) { - dput(dinode); - return ERR_PTR(-EIO); - } - if (!(link = hpfs_get_ea(inode->i_sb, fnode, "SYMLINK", &len))) { - brelse(bh); - dput(dinode); - return ERR_PTR(-EIO); - } + err = -EIO; + if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) + goto fail; + err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE); brelse(bh); - UPDATE_ATIME(inode); - ddir = lookup_dentry(link, ddir, follow); - kfree(link); - return ddir; -} + if (err) + goto fail; + SetPageUptodate(page); + kunmap(page); + UnlockPage(page); + return 0; +fail: + SetPageError(page); + kunmap(page); + UnlockPage(page); + return err; +} + int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry) { |