diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
commit | e308faf24f68e262d92d294a01ddca7a17e76762 (patch) | |
tree | 22c47cb315811834861f013067878ff664e95abd /fs/affs | |
parent | 30c6397ce63178fcb3e7963ac247f0a03132aca9 (diff) |
Sync with Linux 2.1.46.
Diffstat (limited to 'fs/affs')
-rw-r--r-- | fs/affs/Changes | 20 | ||||
-rw-r--r-- | fs/affs/amigaffs.c | 21 | ||||
-rw-r--r-- | fs/affs/file.c | 80 | ||||
-rw-r--r-- | fs/affs/inode.c | 10 | ||||
-rw-r--r-- | fs/affs/namei.c | 10 |
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)) { |