lkml.org 
[lkml]   [1999]   [Jun]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjecthpfs patch
Hi.
Here goes patch for HPFS against 2.3.9-pre3. It seems to work.
I won't have access to net during holiday, this is the last patch I'm
sending.

Mikulas Patocka
Binary files linux-clean/linux/fs/ext2/inode.c.swp and linux/fs/ext2/inode.c.swp differ
diff -urN -x *.[aos] -x *.rej -x *.orig -x *.flags -x *.tgz -x *.tar.gz -x *.map -x vmlinu* -x zImage -x .* -x bootsect -x setup -x build -x compile.h -x consolemap_deftbl.c -x conmakehash -x mkinst -x mk -x mkdist -x mnt -x hpfs-ro -x asm -x config -x autoconf.h -x version.h -x modversions.h -x modules -x scripts linux-clean/linux/fs/hpfs/Makefile linux/fs/hpfs/Makefile
--- linux-clean/linux/fs/hpfs/Makefile Sat May 15 20:32:50 1999
+++ linux/fs/hpfs/Makefile Fri Jun 25 18:09:29 1999
@@ -1,5 +1,5 @@
O_TARGET := hpfs.o
-O_OBJS := alloc.o anode.o buffer.o dentry.o dir.o dnode.o ea.o file.o inode.o map.o mmap.o name.o namei.o super.o
+O_OBJS := alloc.o anode.o buffer.o dentry.o dir.o dnode.o ea.o file.o inode.o map.o name.o namei.o super.o
M_OBJS := $(O_TARGET)

include $(TOPDIR)/Rules.make
diff -urN -x *.[aos] -x *.rej -x *.orig -x *.flags -x *.tgz -x *.tar.gz -x *.map -x vmlinu* -x zImage -x .* -x bootsect -x setup -x build -x compile.h -x consolemap_deftbl.c -x conmakehash -x mkinst -x mk -x mkdist -x mnt -x hpfs-ro -x asm -x config -x autoconf.h -x version.h -x modversions.h -x modules -x scripts linux-clean/linux/fs/hpfs/file.c linux/fs/hpfs/file.c
--- linux-clean/linux/fs/hpfs/file.c Wed Jun 23 11:28:15 1999
+++ linux/fs/hpfs/file.c Fri Jun 25 14:40:32 1999
@@ -53,143 +53,111 @@
{
if (IS_IMMUTABLE(i)) return /*-EPERM*/;
i->i_hpfs_n_secs = 0;
- hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
i->i_blocks = 1 + ((i->i_size + 511) >> 9);
+ hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
hpfs_write_inode(i);
}

-ssize_t hpfs_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
+int hpfs_getblk_block(struct inode *inode, long block, int create, int *err, int *created)
{
- struct inode *inode = filp->f_dentry->d_inode;
- int i,j;
- int a = generic_file_read(filp, buf, count, ppos);
- if (inode->i_hpfs_conv != CONV_TEXT || a < 0) {
- return a;
- }
- for (i = 0, j = 0; i < a; i++) {
- char c;
- int error;
- if ((error = get_user(c, buf + i))) return error;
- if (c != '\r') {
- if (i != j) put_user(c, buf + j);
- j++;
+ int add;
+ int sec = 0;
+ down(&inode->i_sem);
+ if (err) *err = 0;
+ if (created) *created = 0;
+ if (!inode->i_blocks) {
+ hpfs_error(inode->i_sb, "hpfs_get_block: inode %08x has no blocks", inode->i_ino);
+ if (err) *err = -EFSERROR;
+ up(&inode->i_sem);
+ return 0;
+ }
+ if (block < ((add = inode->i_blocks - 1))) {
+ int bm;
+ if (!(bm = hpfs_bmap(inode, block))) {
+ hpfs_error(inode->i_sb, "hpfs_get_block: cound not bmap block %08x, inode %08x, size %08x", (int)block, inode->i_ino, (int)inode->i_size);
+ *err = -EFSERROR;
}
+ up(&inode->i_sem);
+ return bm;
+ }
+ if (!create) {
+ if (err) *err = -EFBIG;
+ up(&inode->i_sem);
+ return 0;
}
- return j;
+ if (created) *created = 1;
+ while (add <= block) {
+ if ((sec = hpfs_add_sector_to_btree(inode->i_sb, inode->i_ino, 1, add)) == -1) {
+ if (err) *err = -ENOSPC;
+ hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1);
+ return 0;
+ } /* FIXME: clear block */
+ add++;
+ }
+ inode->i_blocks = add + 1;
+ up(&inode->i_sem);
+ return sec;
}

-ssize_t hpfs_file_write(struct file *filp, const char *buf, size_t count,
- loff_t *ppos)
+/* copied from ext2fs */
+static int hpfs_get_block(struct inode *inode, unsigned long block, struct buffer_head *bh, int update)
{
- struct inode *i = filp->f_dentry->d_inode;
- int carry, error = 0;
- const char *start = buf;
- if (!i) return -EINVAL;
- if (!S_ISREG(i->i_mode)) return -EINVAL;
- if (IS_IMMUTABLE(i)) return -EPERM;
- if (filp->f_flags & O_APPEND) *ppos = i->i_size;
- if (count <= 0) return 0;
- if ((unsigned)(*ppos+count) >= 0x80000000U || (unsigned)count >= 0x80000000U) return -EFBIG;
- carry = 0;
- while (count || carry) {
- int ii, add = 0;
- secno sec = 0; /* Go away, uninitialized variable warning */
- int offset, size, written;
- char ch;
- struct buffer_head *bh;
- char *data;
- offset = *ppos & 0x1ff;
- size = count > 0x200 - offset ? 0x200 - offset : count;
- if ((*ppos >> 9) < ((i->i_size + 0x1ff) >> 9)) {
- i->i_hpfs_n_secs = 0;
- if (!(sec = hpfs_bmap(i, *ppos >> 9))) {
- hpfs_error(i->i_sb, "bmap failed, file %08x, fsec %08x",
- i->i_ino, *ppos >> 9);
- error =- EFSERROR;
- break;
- }
- } else for (ii = (i->i_size + 0x1ff) >> 9, add = 1; ii <= *ppos >> 9; ii++) {
- if ((sec = hpfs_add_sector_to_btree(i->i_sb, i->i_ino, 1, ii)) == -1) {
- hpfs_truncate(i);
- return -ENOSPC;
- }
- if (*ppos != i->i_size)
- if ((data = hpfs_get_sector(i->i_sb, sec, &bh))) {
- memset(data, 0, 512);
- mark_buffer_dirty(bh, 0);
- brelse(bh);
- }
- i->i_size = 0x200 * ii + 1;
- i->i_blocks++;
- /*mark_inode_dirty(i);*/i->i_hpfs_dirty = 1;
- if (i->i_sb->s_hpfs_chk >= 2) {
- secno bsec;
- bsec = hpfs_bmap(i, ii);
- if (sec != bsec) {
- hpfs_error(i->i_sb, "sec == %08x, bmap returns %08x", sec, bsec);
- error = -EFSERROR;
- break;
- }
- }
- PRINTK(("file_write: added %08x\n", sec));
- }
- if (!sec || sec == 15) {
- hpfs_error(i->i_sb, "bmap returned empty sector");
- error = -EFSERROR;
- break;
- }
- if (i->i_sb->s_hpfs_chk)
- if (hpfs_chk_sectors(i->i_sb, sec, 1, "data")) {
- error = -EFSERROR;
- break;
- }
- if ((!offset && size == 0x200) || add)
- data = hpfs_get_sector(i->i_sb, sec, &bh);
- else data = hpfs_map_sector(i->i_sb, sec, &bh, 0);
- if (!data) {
- error = -EIO;
- break;
- }
- if (i->i_hpfs_conv != CONV_TEXT) {
- memcpy_fromfs(data + offset, buf, written = size);
- buf += size;
- } else {
- int left;
- char *to;
- /* LF->CR/LF conversion, stolen from fat fs */
- written = left = 0x200 - offset;
- to = (char *) bh->b_data + (*ppos & 0x1ff);
- if (carry) {
- *to++ = '\n';
- left--;
- carry = 0;
- }
- for (size = 0; size < count && left; size++) {
- if ((error = get_user(ch, buf++))) break;
- if (ch == '\n') {
- *to++ = '\r';
- left--;
- }
- if (!left) carry = 1;
- else {
- *to++ = ch;
- left--;
- }
- }
- written -= left;
+ if (!bh->b_blocknr) {
+ int error, created;
+ unsigned long blocknr;
+
+ blocknr = hpfs_getblk_block(inode, block, 1, &error, &created);
+ if (!blocknr) {
+ if (!error)
+ error = -ENOSPC;
+ return error;
}
- update_vm_cache(i, *ppos, bh->b_data + (*ppos & 0x1ff), written);
- *ppos += written;
- if (*ppos > i->i_size) {
- i->i_size = *ppos;
- /*mark_inode_dirty(i);*/i->i_hpfs_dirty = 1;
+
+ bh->b_dev = inode->i_dev;
+ bh->b_blocknr = blocknr;
+
+ if (!update)
+ return 0;
+
+ if (created) {
+ memset(bh->b_data, 0, bh->b_size);
+ set_bit(BH_Uptodate, &bh->b_state);
+ return 0;
}
- mark_buffer_dirty(bh, 0);
- brelse(bh);
- count -= size;
- }
- if (start == buf) return error;
- i->i_mtime = CURRENT_TIME;
- /*mark_inode_dirty(i);*/i->i_hpfs_dirty = 1;
- return buf - start;
+ }
+
+ if (!update)
+ return 0;
+
+ lock_kernel();
+ ll_rw_block(READ, 1, &bh);
+ wait_on_buffer(bh);
+ unlock_kernel();
+
+ return buffer_uptodate(bh) ? 0 : -EIO;
+}
+
+int hpfs_writepage(struct file *file, struct page *page)
+{
+ return block_write_full_page(file, page, hpfs_get_block);
+}
+
+long hpfs_write_one_page (struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char *buf)
+{
+ return block_write_partial_page(file, page, offset, bytes, buf, hpfs_get_block);
}
+
+
+ssize_t hpfs_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
+{
+ ssize_t retval;
+ struct inode *inode = file->f_dentry->d_inode;
+ retval = generic_file_write(file, buf, count, ppos, hpfs_write_one_page);
+ if (retval > 0) {
+ /*remove_suid(inode);*/
+ inode->i_mtime = CURRENT_TIME;
+ inode->i_hpfs_dirty = 1;
+ }
+ return retval;
+}
+
diff -urN -x *.[aos] -x *.rej -x *.orig -x *.flags -x *.tgz -x *.tar.gz -x *.map -x vmlinu* -x zImage -x .* -x bootsect -x setup -x build -x compile.h -x consolemap_deftbl.c -x conmakehash -x mkinst -x mk -x mkdist -x mnt -x hpfs-ro -x asm -x config -x autoconf.h -x version.h -x modversions.h -x modules -x scripts linux-clean/linux/fs/hpfs/hpfs_fn.h linux/fs/hpfs/hpfs_fn.h
--- linux-clean/linux/fs/hpfs/hpfs_fn.h Wed Jun 2 20:19:44 1999
+++ linux/fs/hpfs/hpfs_fn.h Fri Jun 25 14:43:42 1999
@@ -21,6 +21,7 @@
#include <asm/bitops.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
+#include <linux/smp_lock.h>

#include <stdarg.h>

@@ -259,6 +260,7 @@
void hpfs_truncate(struct inode *);
ssize_t hpfs_file_read(struct file *, char *, size_t, loff_t *);
ssize_t hpfs_file_write(struct file *, const char *, size_t, loff_t *);
+int hpfs_writepage (struct file *, struct page *);

/* inode.c */

diff -urN -x *.[aos] -x *.rej -x *.orig -x *.flags -x *.tgz -x *.tar.gz -x *.map -x vmlinu* -x zImage -x .* -x bootsect -x setup -x build -x compile.h -x consolemap_deftbl.c -x conmakehash -x mkinst -x mk -x mkdist -x mnt -x hpfs-ro -x asm -x config -x autoconf.h -x version.h -x modversions.h -x modules -x scripts linux-clean/linux/fs/hpfs/inode.c linux/fs/hpfs/inode.c
--- linux-clean/linux/fs/hpfs/inode.c Fri Jun 25 14:05:56 1999
+++ linux/fs/hpfs/inode.c Fri Jun 25 14:05:16 1999
@@ -11,7 +11,7 @@
static const struct file_operations hpfs_file_ops =
{
NULL, /* lseek - default */
- hpfs_file_read, /* read */
+ generic_file_read, /* read */
hpfs_file_write, /* write */
NULL, /* readdir - bad */
NULL, /* poll - default */
@@ -44,9 +44,9 @@
(int (*)(struct inode *, int))
&hpfs_bmap, /* bmap */
block_read_full_page, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- &hpfs_truncate, /* truncate */
+ hpfs_writepage, /* writepage */
+ block_flushpage, /* flushpage */
+ hpfs_truncate, /* truncate */
NULL, /* permission */
NULL, /* smap */
NULL, /* revalidate */
@@ -92,7 +92,7 @@
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
- NULL, /* revalidate */
+ NULL /* revalidate */
};

const struct inode_operations hpfs_symlink_iops =
@@ -116,7 +116,7 @@
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
- NULL, /* revalidate */
+ NULL /* revalidate */
};


@@ -128,7 +128,6 @@
unsigned char *ea;
int ea_size;
i->i_op = 0;
- /*i->i_hpfs_sem = MUTEX;*/
init_MUTEX(&i->i_hpfs_sem);
i->i_uid = sb->s_hpfs_uid;
i->i_gid = sb->s_hpfs_gid;
diff -urN -x *.[aos] -x *.rej -x *.orig -x *.flags -x *.tgz -x *.tar.gz -x *.map -x vmlinu* -x zImage -x .* -x bootsect -x setup -x build -x compile.h -x consolemap_deftbl.c -x conmakehash -x mkinst -x mk -x mkdist -x mnt -x hpfs-ro -x asm -x config -x autoconf.h -x version.h -x modversions.h -x modules -x scripts linux-clean/linux/fs/hpfs/mmap.c linux/fs/hpfs/mmap.c
--- linux-clean/linux/fs/hpfs/mmap.c Sat May 15 20:32:50 1999
+++ linux/fs/hpfs/mmap.c Thu Jan 1 01:00:00 1970
@@ -1,128 +0,0 @@
-/*
- * linux/fs/hpfs/mmap.c
- *
- * taken from fat filesystem
- *
- * Written by Jacques Gelinas (jacques@solucorp.qc.ca)
- * Inspired by fs/nfs/mmap.c (Jon Tombs 15 Aug 1993)
- *
- * Modified for HPFS by Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz)
- *
- * mmap handling for hpfs filesystem
- * (generic_file_mmap may be used only on filesystems that keep zeros
- * in last file sector beyond end)
- */
-
-/*
- * generic_file_mmap doesn't erase the space beyond file end in last sector. :-(
- * Hpfs doesn't keep zeros in last sector. This causes problems with kernel
- * mkdep.c and probably other programs. Additionally this could be a security
- * hole - some interesting data, like pieces of /etc/shadow could be found
- * beyond file end.
- *
- * So, I can't use generic mmap. mmap from fat filesystem looks good, so I used
- * it.
- *
- * BTW. fat uses generic mmap on normal disks. Doesn't it also have above bugs?
- * I don't think Msdos erases space in last sector.
- *
- * If you fix generic_file_mmap, you can remove this file and use it.
- */
-
-#include "hpfs_fn.h"
-
-/*
- * Fill in the supplied page for mmap
- */
-
-static unsigned long hpfs_file_mmap_nopage(
- struct vm_area_struct * area,
- unsigned long address,
- int error_code)
-{
- /*struct inode * inode = area->vm_inode;*/
- struct inode * inode = area->vm_file->f_dentry->d_inode;
- unsigned long page;
- unsigned int clear;
- loff_t pos;
- long gap; /* distance from eof to pos */
-
- page = __get_free_page(GFP_KERNEL);
- if (!page)
- return page;
- address &= PAGE_MASK;
- pos = address - area->vm_start + area->vm_offset;
-
- clear = 0;
- gap = inode->i_size - pos;
- if (gap <= 0){
- /* mmaping beyond end of file */
- clear = PAGE_SIZE;
- }else{
- int cur_read;
- int need_read;
- /*struct file *filp = area->vm_file;*/
- struct file filp;
- if (gap < PAGE_SIZE){
- clear = PAGE_SIZE - gap;
- }
- filp.f_reada = 0;
- filp.f_pos = pos;
- filp.f_dentry=area->vm_file->f_dentry;
- need_read = PAGE_SIZE - clear;
- {
- mm_segment_t cur_fs = get_fs();
- set_fs (KERNEL_DS);
- cur_read = generic_file_read (&filp,(char*)page
- ,need_read,&pos);
- set_fs (cur_fs);
- }
- if (cur_read != need_read){
- hpfs_error(inode->i_sb, "Error while reading an mmap file %08x", inode->i_ino);
- }
- }
- if (clear > 0){
- memset ((char*)page+PAGE_SIZE-clear,0,clear);
- }
- return page;
-}
-
-struct vm_operations_struct hpfs_file_mmap = {
- NULL, /* open */
- NULL, /* close */
- NULL, /* unmap */
- NULL, /* protect */
- NULL, /* sync */
- NULL, /* advise */
- hpfs_file_mmap_nopage, /* nopage */
- NULL, /* wppage */
- NULL, /* swapout */
- NULL, /* swapin */
-};
-
-/*
- * This is used for a general mmap of an msdos file
- * Returns 0 if ok, or a negative error code if not.
- */
-int hpfs_mmap(struct file * file, struct vm_area_struct * vma)
-{
- struct inode *inode = file->f_dentry->d_inode;
- /*printk("start mmap\n");*/
- if (vma->vm_flags & VM_SHARED) /* only PAGE_COW or read-only supported now */
- return -EINVAL;
- if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
- return -EINVAL;
- if (!inode->i_sb || !S_ISREG(inode->i_mode))
- return -EACCES;
- /*if (!IS_RDONLY(inode)) {
- inode->i_atime = CURRENT_TIME;
- mark_inode_dirty(inode);
- }*/
-
- vma->vm_file = file;
- /*inode->i_count++;*/
- file->f_count++;
- vma->vm_ops = &hpfs_file_mmap;
- /*printk("end mmap\n");*/
- return 0;
-}
\
 
 \ /
  Last update: 2005-03-22 13:52    [W:0.028 / U:0.120 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site