patch-1.3.60 linux/fs/msdos/namei.c
Next file: linux/fs/namei.c
Previous file: linux/fs/msdos/msdosfs_syms.c
Back to the patch index
Back to the overall index
- Lines: 414
- Date:
Wed Feb 7 09:39:28 1996
- Orig file:
v1.3.59/linux/fs/msdos/namei.c
- Orig date:
Sun Dec 17 11:43:20 1995
diff -u --recursive --new-file v1.3.59/linux/fs/msdos/namei.c linux/fs/msdos/namei.c
@@ -1,10 +1,13 @@
/*
- * linux/fs/msdos/namei.c
+ * linux/fs/msdos/msdos.c
*
* Written 1992,1993 by Werner Almesberger
* Hidden files 1995 by Albert Cahalan <albert@ccs.neu.edu> <adc@coe.neu.edu>
*/
+#define __NO_VERSION__
+#include <linux/module.h>
+
#include <linux/sched.h>
#include <linux/msdos_fs.h>
#include <linux/kernel.h>
@@ -14,10 +17,11 @@
#include <asm/segment.h>
-#include "msbuffer.h"
+#include "../fat/msbuffer.h"
#define PRINTK(x)
+
/* MS-DOS "device special files" */
static const char *reserved_names[] = {
@@ -33,6 +37,41 @@
static char bad_if_strict[] = "+=,; ";
+void msdos_put_super(struct super_block *sb)
+{
+ fat_put_super(sb);
+ MOD_DEC_USE_COUNT;
+}
+
+struct super_operations msdos_sops = {
+ msdos_read_inode,
+ fat_notify_change,
+ fat_write_inode,
+ fat_put_inode,
+ msdos_put_super,
+ NULL, /* added in 0.96c */
+ fat_statfs,
+ NULL
+};
+
+struct super_block *msdos_read_super(struct super_block *sb,void *data, int silent)
+{
+ struct super_block *res;
+
+ MOD_INC_USE_COUNT;
+
+ sb->s_op = &msdos_sops;
+ res = fat_read_super(sb, data, silent);
+ if (res == NULL)
+ MOD_DEC_USE_COUNT;
+
+ return res;
+}
+
+
+
+
+
/***** Formats an MS-DOS file name. Rejects invalid names. */
static int msdos_format_name(char conv,const char *name,int len,
char *res,int dot_dirs,char dotsOK)
@@ -130,7 +169,7 @@
} else {
scantype = (dotsOK ? SCAN_NOTHID : SCAN_ANY);
}
- return msdos_scan(dir,msdos_name,bh,de,ino,scantype);
+ return fat_scan(dir,msdos_name,bh,de,ino,scantype);
}
/***** Get inode using directory and name */
@@ -157,7 +196,7 @@
return 0;
}
if (len == 2 && name[0] == '.' && name[1] == '.') {
- ino = msdos_parent_ino(dir,0);
+ ino = fat_parent_ino(dir,0);
iput(dir);
if (ino < 0) return ino;
if (!(*result = iget(dir->i_sb,ino))) return -EACCES;
@@ -193,7 +232,7 @@
next = MSDOS_I(*result)->i_old;
iput(*result);
if (!(*result = iget(next->i_sb,next->i_ino))) {
- fs_panic(dir->i_sb,"msdos_lookup: Can't happen");
+ fat_fs_panic(dir->i_sb,"msdos_lookup: Can't happen");
iput(dir);
return -ENOENT;
}
@@ -214,11 +253,11 @@
struct msdos_dir_entry *de;
int res,ino;
- if ((res = msdos_scan(dir,NULL,&bh,&de,&ino,SCAN_ANY)) < 0) {
+ if ((res = fat_scan(dir,NULL,&bh,&de,&ino,SCAN_ANY)) < 0) {
if (res != -ENOENT) return res;
if (dir->i_ino == MSDOS_ROOT_INO) return -ENOSPC;
- if ((res = msdos_add_cluster(dir)) < 0) return res;
- if ((res = msdos_scan(dir,NULL,&bh,&de,&ino,SCAN_ANY)) < 0) return res;
+ if ((res = fat_add_cluster(dir)) < 0) return res;
+ if ((res = fat_scan(dir,NULL,&bh,&de,&ino,SCAN_ANY)) < 0) return res;
}
/*
* XXX all times should be set by caller upon successful completion.
@@ -230,7 +269,7 @@
de->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
de->attr = is_hid ? (de->attr|ATTR_HIDDEN) : (de->attr&~ATTR_HIDDEN);
de->start = 0;
- date_unix2dos(dir->i_mtime,&de->time,&de->date);
+ fat_date_unix2dos(dir->i_mtime,&de->time,&de->date);
de->size = 0;
mark_buffer_dirty(bh, 1);
if ((*result = iget(dir->i_sb,ino)) != NULL)
@@ -260,25 +299,25 @@
return res;
}
is_hid = (name[0]=='.') && (msdos_name[0]!='.');
- lock_creation();
+ fat_lock_creation();
/* Scan for existing file twice, so that creating a file fails
* with -EINVAL if the other (dotfile/nondotfile) exists.
* Else SCAN_ANY would do. Maybe use EACCES, EBUSY, ENOSPC, ENFILE?
*/
- if (msdos_scan(dir,msdos_name,&bh,&de,&ino,SCAN_HID) >= 0) {
- unlock_creation();
+ if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_HID) >= 0) {
+ fat_unlock_creation();
brelse(bh);
iput(dir);
return is_hid ? -EEXIST : -EINVAL;
}
- if (msdos_scan(dir,msdos_name,&bh,&de,&ino,SCAN_NOTHID) >= 0) {
- unlock_creation();
+ if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_NOTHID) >= 0) {
+ fat_unlock_creation();
brelse(bh);
iput(dir);
return is_hid ? -EINVAL : -EEXIST;
}
res = msdos_create_entry(dir,msdos_name,S_ISDIR(mode),is_hid,result);
- unlock_creation();
+ fat_unlock_creation();
iput(dir);
return res;
}
@@ -303,65 +342,6 @@
#endif
-/***** Make a directory */
-int msdos_mkdir(struct inode *dir,const char *name,int len,int mode)
-{
- struct super_block *sb = dir->i_sb;
- struct buffer_head *bh;
- struct msdos_dir_entry *de;
- struct inode *inode,*dot;
- char msdos_name[MSDOS_NAME];
- int ino,res,is_hid;
-
- if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->name_check,name,len,
- msdos_name,0,MSDOS_SB(dir->i_sb)->dotsOK)) < 0) {
- iput(dir);
- return res;
- }
- is_hid = (name[0]=='.') && (msdos_name[0]!='.');
- lock_creation();
- if (msdos_scan(dir,msdos_name,&bh,&de,&ino,SCAN_ANY) >= 0) {
- unlock_creation();
- brelse(bh);
- iput(dir);
- return -EEXIST;
- }
- if ((res = msdos_create_entry(dir,msdos_name,1,is_hid,&inode)) < 0) {
- unlock_creation();
- iput(dir);
- return res;
- }
- dir->i_nlink++;
- inode->i_nlink = 2; /* no need to mark them dirty */
- MSDOS_I(inode)->i_busy = 1; /* prevent lookups */
- if ((res = msdos_add_cluster(inode)) < 0) goto mkdir_error;
- if ((res = msdos_create_entry(inode,MSDOS_DOT,1,0,&dot)) < 0)
- goto mkdir_error;
- dot->i_size = inode->i_size; /* doesn't grow in the 2nd create_entry */
- MSDOS_I(dot)->i_start = MSDOS_I(inode)->i_start;
- dot->i_nlink = inode->i_nlink;
- dot->i_dirt = 1;
- iput(dot);
- if ((res = msdos_create_entry(inode,MSDOS_DOTDOT,1,0,&dot)) < 0)
- goto mkdir_error;
- unlock_creation();
- dot->i_size = dir->i_size;
- MSDOS_I(dot)->i_start = MSDOS_I(dir)->i_start;
- dot->i_nlink = dir->i_nlink;
- dot->i_dirt = 1;
- MSDOS_I(inode)->i_busy = 0;
- iput(dot);
- iput(inode);
- iput(dir);
- return 0;
-mkdir_error:
- iput(inode);
- if (msdos_rmdir(dir,name,len) < 0)
- fs_panic(dir->i_sb,"rmdir in mkdir failed");
- unlock_creation();
- return res;
-}
-
/***** See if directory is empty */
static int msdos_empty(struct inode *dir)
{
@@ -375,7 +355,7 @@
if (MSDOS_I(dir)->i_start) { /* may be zero in mkdir */
pos = 0;
bh = NULL;
- while (msdos_get_entry(dir,&pos,&bh,&de) > -1)
+ while (fat_get_entry(dir,&pos,&bh,&de) > -1)
if (!IS_FREE(de->name) && strncmp(de->name,MSDOS_DOT,
MSDOS_NAME) && strncmp(de->name,MSDOS_DOTDOT,
MSDOS_NAME)) {
@@ -427,6 +407,65 @@
return res;
}
+/***** Make a directory */
+int msdos_mkdir(struct inode *dir,const char *name,int len,int mode)
+{
+ struct super_block *sb = dir->i_sb;
+ struct buffer_head *bh;
+ struct msdos_dir_entry *de;
+ struct inode *inode,*dot;
+ char msdos_name[MSDOS_NAME];
+ int ino,res,is_hid;
+
+ if ((res = msdos_format_name(MSDOS_SB(dir->i_sb)->name_check,name,len,
+ msdos_name,0,MSDOS_SB(dir->i_sb)->dotsOK)) < 0) {
+ iput(dir);
+ return res;
+ }
+ is_hid = (name[0]=='.') && (msdos_name[0]!='.');
+ fat_lock_creation();
+ if (fat_scan(dir,msdos_name,&bh,&de,&ino,SCAN_ANY) >= 0) {
+ fat_unlock_creation();
+ brelse(bh);
+ iput(dir);
+ return -EEXIST;
+ }
+ if ((res = msdos_create_entry(dir,msdos_name,1,is_hid,&inode)) < 0) {
+ fat_unlock_creation();
+ iput(dir);
+ return res;
+ }
+ dir->i_nlink++;
+ inode->i_nlink = 2; /* no need to mark them dirty */
+ MSDOS_I(inode)->i_busy = 1; /* prevent lookups */
+ if ((res = fat_add_cluster(inode)) < 0) goto mkdir_error;
+ if ((res = msdos_create_entry(inode,MSDOS_DOT,1,0,&dot)) < 0)
+ goto mkdir_error;
+ dot->i_size = inode->i_size; /* doesn't grow in the 2nd create_entry */
+ MSDOS_I(dot)->i_start = MSDOS_I(inode)->i_start;
+ dot->i_nlink = inode->i_nlink;
+ dot->i_dirt = 1;
+ iput(dot);
+ if ((res = msdos_create_entry(inode,MSDOS_DOTDOT,1,0,&dot)) < 0)
+ goto mkdir_error;
+ fat_unlock_creation();
+ dot->i_size = dir->i_size;
+ MSDOS_I(dot)->i_start = MSDOS_I(dir)->i_start;
+ dot->i_nlink = dir->i_nlink;
+ dot->i_dirt = 1;
+ MSDOS_I(inode)->i_busy = 0;
+ iput(dot);
+ iput(inode);
+ iput(dir);
+ return 0;
+mkdir_error:
+ iput(inode);
+ if (msdos_rmdir(dir,name,len) < 0)
+ fat_fs_panic(dir->i_sb,"rmdir in mkdir failed");
+ fat_unlock_creation();
+ return res;
+}
+
/***** Unlink a file */
static int msdos_unlinkx(
struct inode *dir,
@@ -493,7 +532,7 @@
int new_ino,exists,error;
if (!strncmp(old_name,new_name,MSDOS_NAME)) goto set_hid;
- exists = msdos_scan(new_dir,new_name,&new_bh,&new_de,&new_ino,SCAN_ANY) >= 0;
+ exists = fat_scan(new_dir,new_name,&new_bh,&new_de,&new_ino,SCAN_ANY) >= 0;
if (*(unsigned char *) old_de->name == DELETED_FLAG) {
if (exists) brelse(new_bh);
return -ENOENT;
@@ -562,7 +601,7 @@
if (!(walk = iget(new_dir->i_sb,new_dir->i_ino))) return -EIO;
/* prevent moving directory below itself */
while (walk->i_ino != MSDOS_ROOT_INO) {
- ino = msdos_parent_ino(walk,1);
+ ino = fat_parent_ino(walk,1);
iput(walk);
if (ino < 0) return ino;
if (ino == old_ino) return -EINVAL;
@@ -570,13 +609,13 @@
}
iput(walk);
/* find free spot */
- while ((error = msdos_scan(new_dir,NULL,&free_bh,&free_de,&free_ino,
+ while ((error = fat_scan(new_dir,NULL,&free_bh,&free_de,&free_ino,
SCAN_ANY)) < 0) {
if (error != -ENOENT) return error;
- error = msdos_add_cluster(new_dir);
+ error = fat_add_cluster(new_dir);
if (error) return error;
}
- exists = msdos_scan(new_dir,new_name,&new_bh,&new_de,&new_ino,SCAN_ANY) >= 0;
+ exists = fat_scan(new_dir,new_name,&new_bh,&new_de,&new_ino,SCAN_ANY) >= 0;
if (!(old_inode = iget(old_dir->i_sb,old_ino))) {
brelse(free_bh);
if (exists) brelse(new_bh);
@@ -636,7 +675,7 @@
}
msdos_read_inode(free_inode);
MSDOS_I(old_inode)->i_busy = 1;
- cache_inval_inode(old_inode);
+ fat_cache_inval_inode(old_inode);
old_inode->i_dirt = 1;
old_de->name[0] = DELETED_FLAG;
mark_buffer_dirty(old_bh, 1);
@@ -650,7 +689,7 @@
brelse(new_bh);
}
if (S_ISDIR(old_inode->i_mode)) {
- if ((error = msdos_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,
+ if ((error = fat_scan(old_inode,MSDOS_DOTDOT,&dotdot_bh,
&dotdot_de,&dotdot_ino,SCAN_ANY)) < 0) goto rename_done;
if (!(dotdot_inode = iget(old_inode->i_sb,dotdot_ino))) {
brelse(dotdot_bh);
@@ -694,18 +733,63 @@
< 0) goto rename_done;
is_hid = (new_name[0]=='.') && (new_msdos_name[0]!='.');
old_hid = (old_name[0]=='.') && (old_msdos_name[0]!='.');
- if ((error = msdos_scan(old_dir,old_msdos_name,&old_bh,&old_de,
+ if ((error = fat_scan(old_dir,old_msdos_name,&old_bh,&old_de,
&old_ino,old_hid?SCAN_HID:SCAN_NOTHID)) < 0) goto rename_done;
- lock_creation();
+ fat_lock_creation();
if (old_dir == new_dir)
error = rename_same_dir(old_dir,old_msdos_name,new_dir,
new_msdos_name,old_bh,old_de,old_ino,is_hid);
else error = rename_diff_dir(old_dir,old_msdos_name,new_dir,
new_msdos_name,old_bh,old_de,old_ino,is_hid);
- unlock_creation();
+ fat_unlock_creation();
brelse(old_bh);
rename_done:
iput(old_dir);
iput(new_dir);
return error;
}
+
+
+/* The public inode operations for the msdos fs */
+struct inode_operations msdos_dir_inode_operations = {
+ &fat_dir_operations, /* default directory file-ops */
+ msdos_create, /* create */
+ msdos_lookup, /* lookup */
+ NULL, /* link */
+ msdos_unlink, /* unlink */
+ NULL, /* symlink */
+ msdos_mkdir, /* mkdir */
+ msdos_rmdir, /* rmdir */
+ NULL, /* mknod */
+ msdos_rename, /* rename */
+ NULL, /* readlink */
+ NULL, /* follow_link */
+ NULL, /* readpage */
+ NULL, /* writepage */
+ fat_bmap, /* bmap */
+ NULL, /* truncate */
+ NULL /* permission */
+};
+
+
+void msdos_read_inode(struct inode *inode)
+{
+ fat_read_inode(inode, &msdos_dir_inode_operations);
+}
+
+
+
+#ifdef MODULE
+int init_module(void)
+{
+ return init_msdos_fs();
+}
+
+
+void cleanup_module(void)
+{
+ unregister_filesystem(&msdos_fs_type);
+}
+
+#endif
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this