patch-2.2.11 linux/fs/fat/misc.c
Next file: linux/fs/filesystems.c
Previous file: linux/fs/fat/inode.c
Back to the patch index
Back to the overall index
- Lines: 284
- Date:
Mon Aug 9 12:04:41 1999
- Orig file:
v2.2.10/linux/fs/fat/misc.c
- Orig date:
Tue Apr 20 14:37:10 1999
diff -u --recursive --new-file v2.2.10/linux/fs/fat/misc.c linux/fs/fat/misc.c
@@ -144,17 +144,17 @@
* represented by inode. The cluster is zero-initialized.
*/
-int fat_add_cluster(struct inode *inode)
+struct buffer_head *fat_add_cluster1(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
int count,nr,limit,last,curr,sector,last_sector,file_cluster;
- struct buffer_head *bh;
+ struct buffer_head *bh, *res=NULL;
int cluster_size = MSDOS_SB(sb)->cluster_size;
if (MSDOS_SB(sb)->fat_bits != 32) {
- if (inode->i_ino == MSDOS_ROOT_INO) return -ENOSPC;
+ if (inode->i_ino == MSDOS_ROOT_INO) return res;
}
- if (!MSDOS_SB(sb)->free_clusters) return -ENOSPC;
+ if (!MSDOS_SB(sb)->free_clusters) return res;
lock_fat(sb);
limit = MSDOS_SB(sb)->clusters;
nr = limit; /* to keep GCC happy */
@@ -170,7 +170,7 @@
if (count >= limit) {
MSDOS_SB(sb)->free_clusters = 0;
unlock_fat(sb);
- return -ENOSPC;
+ return res;
}
fat_access(sb,nr,EOF_FAT(sb));
if (MSDOS_SB(sb)->free_clusters != -1)
@@ -202,7 +202,7 @@
if (!(curr = fat_access(sb,
last = curr,-1))) {
fat_fs_panic(sb,"File without EOF");
- return -ENOSPC;
+ return res;
}
}
PRINTK ((" -- "));
@@ -235,7 +235,10 @@
memset(bh->b_data,0,SECTOR_SIZE);
fat_set_uptodate(sb, bh, 1);
fat_mark_buffer_dirty(sb, bh, 1);
- fat_brelse(sb, bh);
+ if (!res)
+ res=bh;
+ else
+ fat_brelse(sb, bh);
}
}
if (file_cluster != inode->i_blocks/cluster_size){
@@ -257,9 +260,17 @@
#endif
mark_inode_dirty(inode);
}
- return 0;
+ return res;
}
+int fat_add_cluster(struct inode *inode)
+{
+ struct buffer_head *bh = fat_add_cluster1(inode);
+ if (!bh)
+ return -ENOSPC;
+ fat_brelse(inode->i_sb, bh);
+ return 0;
+}
/* Linear day numbers of the respective 1sts in non-leap years. */
@@ -319,10 +330,17 @@
/* Returns the inode number of the directory entry at offset pos. If bh is
non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
- returned in bh. */
+ returned in bh.
+ AV. Most often we do it item-by-item. Makes sense to optimize.
+ AV. OK, there we go: if both bh and de are non-NULL we assume that we just
+ AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
+ AV. It's done in fat_get_entry() (inlined), here the slow case lives.
+ AV. Additionally, when we return -1 (i.e. reached the end of directory)
+ AV. we make bh NULL.
+ */
-int fat_get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
- struct msdos_dir_entry **de)
+int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
+ struct msdos_dir_entry **de, int *ino)
{
struct super_block *sb = dir->i_sb;
int sector, offset;
@@ -330,25 +348,24 @@
while (1) {
offset = *pos;
PRINTK (("get_entry offset %d\n",offset));
+ if (*bh)
+ fat_brelse(sb, *bh);
+ *bh = NULL;
if ((sector = fat_smap(dir,offset >> SECTOR_BITS)) == -1)
return -1;
- PRINTK (("get_entry sector %d %p\n",sector,*bh));
if (!sector)
return -1; /* beyond EOF */
*pos += sizeof(struct msdos_dir_entry);
- if (*bh)
- fat_brelse(sb, *bh);
- PRINTK (("get_entry sector apres brelse\n"));
if (!(*bh = fat_bread(sb, sector))) {
printk("Directory sread (sector 0x%x) failed\n",sector);
continue;
}
- PRINTK (("get_entry apres sread\n"));
- *de = (struct msdos_dir_entry *) ((*bh)->b_data+(offset &
- (SECTOR_SIZE-1)));
- return (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >>
- MSDOS_DIR_BITS);
+ break;
}
+ *de = (struct msdos_dir_entry*)((*bh)->b_data+(offset&(SECTOR_SIZE-1)));
+ *ino = (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >>
+ MSDOS_DIR_BITS);
+ return 0;
}
@@ -393,14 +410,6 @@
#define RSS_FREE /* search for free entry */ \
{ \
done = IS_FREE(data[entry].name); \
- if (done) { \
- inode = iget(sb,sector*MSDOS_DPS+entry); \
- if (inode) { \
- /* Directory slots of busy deleted files aren't available yet. */ \
- done = !MSDOS_I(inode)->i_busy; \
- iput(inode); \
- } \
- } \
}
#define RSS_COUNT /* count subdirectories */ \
@@ -412,11 +421,10 @@
static int raw_scan_sector(struct super_block *sb,int sector,const char *name,
int *number,int *ino,struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de,char scantype)
+ struct msdos_dir_entry **res_de)
{
struct buffer_head *bh;
struct msdos_dir_entry *data;
- struct inode *inode;
int entry,start,done;
if (!(bh = fat_bread(sb,sector)))
@@ -426,11 +434,6 @@
/* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */
if (name) {
RSS_NAME
- if (done && scantype) { /* scantype != SCAN_ANY */
- done = (data[entry].attr & ATTR_HIDDEN)
- ? (scantype==SCAN_HID)
- : (scantype==SCAN_NOTHID);
- }
} else {
if (!ino) RSS_COUNT
else {
@@ -464,13 +467,13 @@
*/
static int raw_scan_root(struct super_block *sb,const char *name,int *number,int *ino,
- struct buffer_head **res_bh,struct msdos_dir_entry **res_de,char scantype)
+ struct buffer_head **res_bh,struct msdos_dir_entry **res_de)
{
int count,cluster;
for (count = 0; count < MSDOS_SB(sb)->dir_entries/MSDOS_DPS; count++) {
if ((cluster = raw_scan_sector(sb,MSDOS_SB(sb)->dir_start+count,
- name,number,ino,res_bh,res_de,scantype)) >= 0) return cluster;
+ name,number,ino,res_bh,res_de)) >= 0) return cluster;
}
return -ENOENT;
}
@@ -483,7 +486,7 @@
static int raw_scan_nonroot(struct super_block *sb,int start,const char *name,
int *number,int *ino,struct buffer_head **res_bh,struct msdos_dir_entry
- **res_de,char scantype)
+ **res_de)
{
int count,cluster;
@@ -494,7 +497,7 @@
for (count = 0; count < MSDOS_SB(sb)->cluster_size; count++) {
if ((cluster = raw_scan_sector(sb,(start-2)*
MSDOS_SB(sb)->cluster_size+MSDOS_SB(sb)->data_start+
- count,name,number,ino,res_bh,res_de,scantype)) >= 0)
+ count,name,number,ino,res_bh,res_de)) >= 0)
return cluster;
}
if (!(start = fat_access(sb,start,-1))) {
@@ -519,12 +522,12 @@
static int raw_scan(struct super_block *sb, int start, const char *name,
int *number, int *ino, struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de, char scantype)
+ struct msdos_dir_entry **res_de)
{
if (start) return raw_scan_nonroot
- (sb,start,name,number,ino,res_bh,res_de,scantype);
+ (sb,start,name,number,ino,res_bh,res_de);
else return raw_scan_root
- (sb,name,number,ino,res_bh,res_de,scantype);
+ (sb,name,number,ino,res_bh,res_de);
}
@@ -532,6 +535,11 @@
* fat_parent_ino returns the inode number of the parent directory of dir.
* File creation has to be deferred while fat_parent_ino is running to
* prevent renames.
+ *
+ * AV. Bad, bad, bad... We need a mapping that would give us inode by
+ * first cluster. Sheeeeit... OK, we can do it on fat_fill_inode() and
+ * update on fat_add_cluster(). When will we remove it? fat_clear_inode()
+ * and fat_truncate() to zero?
*/
int fat_parent_ino(struct inode *dir,int locked)
@@ -544,7 +552,7 @@
if (dir->i_ino == MSDOS_ROOT_INO) return dir->i_ino;
if (!locked) fat_lock_creation(); /* prevent renames */
if ((curr = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,MSDOS_DOTDOT,
- &zero,NULL,NULL,NULL,SCAN_ANY)) < 0) {
+ &zero,NULL,NULL,NULL)) < 0) {
if (!locked) fat_unlock_creation();
return curr;
}
@@ -553,7 +561,7 @@
else {
PRINTK(("fat_parent_ino: Debug 2\n"));
if ((prev = raw_scan(dir->i_sb,curr,MSDOS_DOTDOT,&zero,NULL,
- NULL,NULL,SCAN_ANY)) < 0) {
+ NULL,NULL)) < 0) {
PRINTK(("fat_parent_ino: Debug 3 prev=%d\n", prev));
if (!locked) fat_unlock_creation();
return prev;
@@ -563,7 +571,7 @@
prev = MSDOS_SB(dir->i_sb)->root_cluster;
}
if ((error = raw_scan(dir->i_sb,prev,NULL,&curr,&nr,NULL,
- NULL,SCAN_ANY)) < 0) {
+ NULL)) < 0) {
PRINTK(("fat_parent_ino: Debug 5 error=%d\n", error));
if (!locked) fat_unlock_creation();
return error;
@@ -587,12 +595,12 @@
count = 0;
if ((dir->i_ino == MSDOS_ROOT_INO) &&
(MSDOS_SB(dir->i_sb)->fat_bits != 32)) {
- (void) raw_scan_root(dir->i_sb,NULL,&count,NULL,NULL,NULL,SCAN_ANY);
+ (void) raw_scan_root(dir->i_sb,NULL,&count,NULL,NULL,NULL);
} else {
if ((dir->i_ino != MSDOS_ROOT_INO) &&
!MSDOS_I(dir)->i_start) return 0; /* in mkdir */
else (void) raw_scan_nonroot(dir->i_sb,MSDOS_I(dir)->i_start,
- NULL,&count,NULL,NULL,NULL,SCAN_ANY);
+ NULL,&count,NULL,NULL,NULL);
}
return count;
}
@@ -604,11 +612,11 @@
*/
int fat_scan(struct inode *dir,const char *name,struct buffer_head **res_bh,
- struct msdos_dir_entry **res_de,int *ino, char scantype)
+ struct msdos_dir_entry **res_de,int *ino)
{
int res;
res = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,
- name, NULL, ino, res_bh, res_de, scantype);
+ name, NULL, ino, res_bh, res_de);
return res<0 ? res : 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)