summaryrefslogtreecommitdiffstats
path: root/fs/affs
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-07-20 14:56:40 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-07-20 14:56:40 +0000
commite308faf24f68e262d92d294a01ddca7a17e76762 (patch)
tree22c47cb315811834861f013067878ff664e95abd /fs/affs
parent30c6397ce63178fcb3e7963ac247f0a03132aca9 (diff)
Sync with Linux 2.1.46.
Diffstat (limited to 'fs/affs')
-rw-r--r--fs/affs/Changes20
-rw-r--r--fs/affs/amigaffs.c21
-rw-r--r--fs/affs/file.c80
-rw-r--r--fs/affs/inode.c10
-rw-r--r--fs/affs/namei.c10
5 files changed, 66 insertions, 75 deletions
diff --git a/fs/affs/Changes b/fs/affs/Changes
index a65dc326a..b19c24ae6 100644
--- a/fs/affs/Changes
+++ b/fs/affs/Changes
@@ -13,11 +13,25 @@ Known bugs:
reads basically work (but all files are of size 0).
Alas, I've got no alpha to debug. :-(
- If an affs mounted filesystem is exported via
- nfs, it cannot be written to. No networking to
- test that, either. :-(
+ nfs, it cannot be written to.
+ As soon as I have my network up and running, I'll
+ try to fix this.
+- The partition checker (drivers/block/genhd.c)
+ doesn't work with devices which have 256 byte
+ blocks (some very old SCSI drives).
Please direct bug reports to: hjw@zvw.de
+Version 3.5
+-----------
+
+- Extension block caches are now allocated on
+ demand instead of when a file is opened, as
+ files can be read and written without opening
+ them (e. g. the loopback device does this).
+
+- Removed an unused function.
+
Version 3.4
-----------
@@ -80,7 +94,7 @@ Version 3.0
interface in Linux 1.3.
- Write support.
- Support for hard and symbolic links.
-- Lots of things I remeber even less ...
+- Lots of things I remember even less ...
Version 2.0
-----------
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index 4afd66e49..7ddb54a62 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -26,27 +26,6 @@ static char ErrorBuffer[256];
*
*/
-/* Find the next used hash entry at or after *HASH_POS in a directory's hash
- table. *HASH_POS is assigned that entry's number. DIR_DATA points to
- the directory header block in memory. If there are no more entries,
- 0 is returned. Otherwise, the key number in the next used hash slot
- is returned. */
-
-static int
-affs_find_next_hash_entry(int hsize, void *dir_data, int *hash_pos)
-{
- struct dir_front *dir_front = dir_data;
- int i;
-
- for (i = *hash_pos; i < hsize; i++)
- if (dir_front->hashtable[i] != 0)
- break;
- if (i >= hsize)
- return 0;
- *hash_pos = i;
- return htonl(dir_front->hashtable[i]);
-}
-
/* Set *NAME to point to the file name in a file header block in memory
pointed to by FH_DATA. The length of the name is returned. */
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 46b10bcb1..7777e4763 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -43,8 +43,8 @@ static long affs_file_write(struct inode *inode, struct file *filp, const char *
unsigned long count);
static long affs_file_write_ofs(struct inode *inode, struct file *filp, const char *buf,
unsigned long count);
-static int affs_open_file(struct inode *inode, struct file *filp);
static int affs_release_file(struct inode *inode, struct file *filp);
+static int alloc_ext_cache(struct inode *inode);
static struct file_operations affs_file_operations = {
NULL, /* lseek - default */
@@ -54,7 +54,7 @@ static struct file_operations affs_file_operations = {
NULL, /* poll - default */
NULL, /* ioctl - default */
generic_file_mmap, /* mmap */
- affs_open_file, /* special open is needed */
+ NULL, /* no special open */
affs_release_file, /* release */
file_fsync /* brute force, but works */
};
@@ -87,7 +87,7 @@ static struct file_operations affs_file_operations_ofs = {
NULL, /* poll - default */
NULL, /* ioctl - default */
NULL, /* mmap */
- affs_open_file, /* special open is needed */
+ NULL, /* no special open */
affs_release_file, /* release */
file_fsync /* brute force, but works */
};
@@ -248,9 +248,9 @@ affs_bmap(struct inode *inode, int block)
return 0;
}
if (!inode->u.affs_i.i_ec) {
- affs_error(inode->i_sb,"bmap","No extension cache for open file (inode=%lu)",
- inode->i_ino);
- return 0;
+ if (alloc_ext_cache(inode)) {
+ return 0;
+ }
}
/* Try to find the requested key in the cache.
@@ -582,6 +582,12 @@ affs_file_write(struct inode *inode, struct file *filp, const char *buf, unsigne
iput(inode);
return -EINVAL;
}
+ if (!inode->u.affs_i.i_ec) {
+ if (alloc_ext_cache(inode)) {
+ iput(inode);
+ return -ENOMEM;
+ }
+ }
if (filp->f_flags & O_APPEND) {
pos = inode->i_size;
} else
@@ -861,40 +867,6 @@ affs_truncate(struct inode *inode)
}
static int
-affs_open_file(struct inode *inode, struct file *filp)
-{
- int error;
- u32 key;
- int i;
-
- pr_debug("AFFS: open_file(ino=%lu)\n",inode->i_ino);
-
- error = 0;
- inode->u.affs_i.i_cache_users++;
- lock_super(inode->i_sb);
- if (!inode->u.affs_i.i_ec) {
- inode->u.affs_i.i_ec = (struct ext_cache *)get_free_page(GFP_KERNEL);
- if (!inode->u.affs_i.i_ec) {
- affs_error(inode->i_sb,"open_file","Cache allocation failed");
- error = ENOMEM;
- } else {
- /* We only have to initialize non-zero values.
- * get_free_page() zeroed the page already.
- */
- key = inode->u.affs_i.i_original ? inode->u.affs_i.i_original : inode->i_ino;
- inode->u.affs_i.i_ec->ec[0] = key;
- for (i = 0; i < 4; i++) {
- inode->u.affs_i.i_ec->kc[i].kc_this_key = key;
- inode->u.affs_i.i_ec->kc[i].kc_last = -1;
- }
- }
- }
- unlock_super(inode->i_sb);
-
- return error;
-}
-
-static int
affs_release_file(struct inode *inode, struct file *filp)
{
struct affs_zone *zone;
@@ -916,13 +888,35 @@ affs_release_file(struct inode *inode, struct file *filp)
unlock_super(inode->i_sb);
}
}
+ return 0;
+}
+
+static int
+alloc_ext_cache(struct inode *inode)
+{
+ s32 key;
+ int i;
+
lock_super(inode->i_sb);
- if (--inode->u.affs_i.i_cache_users == 0) {
+ if (!inode->u.affs_i.i_ec) {
+ inode->u.affs_i.i_ec = (struct ext_cache *)get_free_page(GFP_KERNEL);
if (inode->u.affs_i.i_ec) {
- free_page((unsigned long)inode->u.affs_i.i_ec);
- inode->u.affs_i.i_ec = NULL;
+ /* We only have to initialize non-zero values.
+ * get_free_page() zeroed the page already.
+ */
+ key = inode->u.affs_i.i_original ? inode->u.affs_i.i_original : inode->i_ino;
+ inode->u.affs_i.i_ec->ec[0] = key;
+ for (i = 0; i < 4; i++) {
+ inode->u.affs_i.i_ec->kc[i].kc_this_key = key;
+ inode->u.affs_i.i_ec->kc[i].kc_last = -1;
+ }
}
}
unlock_super(inode->i_sb);
+
+ if (!inode->u.affs_i.i_ec) {
+ affs_error(inode->i_sb,"alloc_ext_cache","Cache allocation failed");
+ return -ENOMEM;
+ }
return 0;
}
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 2805f1ccf..a1e380cce 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -691,7 +691,6 @@ affs_read_inode(struct inode *inode)
inode->u.affs_i.i_pa_next = 0;
inode->u.affs_i.i_pa_last = 0;
inode->u.affs_i.i_ec = NULL;
- inode->u.affs_i.i_cache_users = 0;
inode->u.affs_i.i_lastblock = -1;
inode->i_nlink = 1;
inode->i_mode = 0;
@@ -870,6 +869,12 @@ static void
affs_put_inode(struct inode *inode)
{
pr_debug("AFFS: put_inode(ino=%lu, nlink=%u)\n",inode->i_ino,inode->i_nlink);
+ lock_super(inode->i_sb);
+ if (inode->u.affs_i.i_ec) {
+ free_page((unsigned long)inode->u.affs_i.i_ec);
+ inode->u.affs_i.i_ec = NULL;
+ }
+ unlock_super(inode->i_sb);
if (inode->i_nlink) {
return;
}
@@ -899,7 +904,7 @@ affs_new_inode(const struct inode *dir)
return NULL;
}
- atomic_set(&inode->i_count, 1);
+ inode->i_count = 1;
inode->i_nlink = 1;
inode->i_dev = sb->s_dev;
inode->i_uid = current->fsuid;
@@ -921,7 +926,6 @@ affs_new_inode(const struct inode *dir)
inode->u.affs_i.i_pa_next = 0;
inode->u.affs_i.i_pa_last = 0;
inode->u.affs_i.i_ec = NULL;
- inode->u.affs_i.i_cache_users = 0;
inode->u.affs_i.i_lastblock = -1;
insert_inode_hash(inode);
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 5ea649425..ce04df073 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -343,7 +343,7 @@ affs_rmdir(struct inode *dir, const char *name, int len)
retval = -ENOTEMPTY;
goto rmdir_done;
}
- if (atomic_read(&inode->i_count) > 1) {
+ if (inode->i_count > 1) {
retval = -EBUSY;
goto rmdir_done;
}
@@ -512,7 +512,7 @@ subdir(struct inode *new_inode, struct inode *old_inode)
int ino;
int result;
- atomic_inc(&new_inode->i_count);
+ new_inode->i_count++;
result = 0;
for (;;) {
if (new_inode == old_inode) {
@@ -566,12 +566,12 @@ start_up:
old_bh = affs_find_entry(old_dir,old_name,old_len,&old_ino);
if (!old_bh)
goto end_rename;
- old_inode = __iget(old_dir->i_sb,old_ino,0);
+ old_inode = iget(old_dir->i_sb,old_ino);
if (!old_inode)
goto end_rename;
new_bh = affs_find_entry(new_dir,new_name,new_len,&new_ino);
if (new_bh) {
- new_inode = __iget(new_dir->i_sb,new_ino,0);
+ new_inode = iget(new_dir->i_sb,new_ino);
if (!new_inode) { /* What does this mean? */
affs_brelse(new_bh);
new_bh = NULL;
@@ -592,7 +592,7 @@ start_up:
if (!empty_dir(new_bh,AFFS_I2HSIZE(new_inode)))
goto end_rename;
retval = -EBUSY;
- if (atomic_read(&new_inode->i_count) > 1)
+ if (new_inode->i_count > 1)
goto end_rename;
}
if (S_ISDIR(old_inode->i_mode)) {