summaryrefslogtreecommitdiffstats
path: root/fs/umsdos/emd.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/umsdos/emd.c')
-rw-r--r--fs/umsdos/emd.c259
1 files changed, 73 insertions, 186 deletions
diff --git a/fs/umsdos/emd.c b/fs/umsdos/emd.c
index 2f56b0404..6a4e99c04 100644
--- a/fs/umsdos/emd.c
+++ b/fs/umsdos/emd.c
@@ -30,46 +30,12 @@ ssize_t umsdos_file_read_kmem ( struct file *filp,
char *buf,
size_t count)
{
- int ret;
-
+ ssize_t ret;
mm_segment_t old_fs = get_fs ();
set_fs (KERNEL_DS);
-
- PRINTK ((KERN_DEBUG "umsdos_file_read_kmem /mn/: Checkin: filp=%p, buf=%p, size=%d\n", filp, buf, count));
- PRINTK ((KERN_DEBUG " inode=%lu, i_size=%lu\n", filp->f_dentry->d_inode->i_ino, filp->f_dentry->d_inode->i_size));
- PRINTK ((KERN_DEBUG " f_pos=%Lu\n", filp->f_pos));
- PRINTK ((KERN_DEBUG " name=%.*s\n", (int) filp->f_dentry->d_name.len, filp->f_dentry->d_name.name));
- PRINTK ((KERN_DEBUG " i_binary(sb)=%d\n", MSDOS_I (filp->f_dentry->d_inode)->i_binary));
- PRINTK ((KERN_DEBUG " f_count=%d, f_flags=%d\n", filp->f_count, filp->f_flags));
- PRINTK ((KERN_DEBUG " f_owner=%d\n", filp->f_owner.uid));
- PRINTK ((KERN_DEBUG " f_version=%ld\n", filp->f_version));
- PRINTK ((KERN_DEBUG " f_reada=%ld, f_ramax=%ld, f_raend=%ld, f_ralen=%ld, f_rawin=%ld\n", filp->f_reada, filp->f_ramax, filp->f_raend, filp->f_ralen, filp->f_rawin));
-
MSDOS_I (filp->f_dentry->d_inode)->i_binary = 2;
-
ret = fat_file_read (filp, buf, count, &filp->f_pos);
- PRINTK ((KERN_DEBUG "fat_file_read returned with %d!\n", ret));
-
- PRINTK ((KERN_DEBUG " (ret) inode=%lu, i_size=%lu\n", filp->f_dentry->d_inode->i_ino, filp->f_dentry->d_inode->i_size));
- PRINTK ((KERN_DEBUG " (ret) f_pos=%Lu\n", filp->f_pos));
- PRINTK ((KERN_DEBUG " (ret) name=%.*s\n", (int) filp->f_dentry->d_name.len, filp->f_dentry->d_name.name));
- PRINTK ((KERN_DEBUG " (ret) i_binary(sb)=%d\n", MSDOS_I (filp->f_dentry->d_inode)->i_binary));
- PRINTK ((KERN_DEBUG " (ret) f_count=%d, f_flags=%d\n", filp->f_count, filp->f_flags));
- PRINTK ((KERN_DEBUG " (ret) f_owner=%d\n", filp->f_owner.uid));
- PRINTK ((KERN_DEBUG " (ret) f_version=%ld\n", filp->f_version));
- PRINTK ((KERN_DEBUG " (ret) f_reada=%ld, f_ramax=%ld, f_raend=%ld, f_ralen=%ld, f_rawin=%ld\n", filp->f_reada, filp->f_ramax, filp->f_raend, filp->f_ralen, filp->f_rawin));
-
-#if 0
- {
- struct umsdos_dirent *mydirent = buf;
-
- Printk ((KERN_DEBUG " (DDD) uid=%d\n", mydirent->uid));
- Printk ((KERN_DEBUG " (DDD) gid=%d\n", mydirent->gid));
- Printk ((KERN_DEBUG " (DDD) name=>%.20s<\n", mydirent->name));
- }
-#endif
-
set_fs (old_fs);
return ret;
}
@@ -85,34 +51,30 @@ ssize_t umsdos_file_write_kmem_real (struct file * filp,
const char *buf,
size_t count)
{
- ssize_t ret;
mm_segment_t old_fs = get_fs ();
-
- set_fs (KERNEL_DS);
-
- PRINTK ((KERN_DEBUG "umsdos_file_write_kmem /mn/: Checkin: filp=%p, buf=%p, size=%d\n", filp, buf, count));
- PRINTK ((KERN_DEBUG " struct dentry=%p\n", filp->f_dentry));
- PRINTK ((KERN_DEBUG " struct inode=%p\n", filp->f_dentry->d_inode));
- PRINTK ((KERN_DEBUG " inode=%lu, i_size=%lu\n", filp->f_dentry->d_inode->i_ino, filp->f_dentry->d_inode->i_size));
- PRINTK ((KERN_DEBUG " f_pos=%Lu\n", filp->f_pos));
- PRINTK ((KERN_DEBUG " name=%.*s\n", (int) filp->f_dentry->d_name.len, filp->f_dentry->d_name.name));
- PRINTK ((KERN_DEBUG " i_binary(sb)=%d\n", MSDOS_I (filp->f_dentry->d_inode)->i_binary));
- PRINTK ((KERN_DEBUG " f_count=%d, f_flags=%d\n", filp->f_count, filp->f_flags));
- PRINTK ((KERN_DEBUG " f_owner=%d\n", filp->f_owner.uid));
- PRINTK ((KERN_DEBUG " f_version=%ld\n", filp->f_version));
- PRINTK ((KERN_DEBUG " f_reada=%ld, f_ramax=%ld, f_raend=%ld, f_ralen=%ld, f_rawin=%ld\n", filp->f_reada, filp->f_ramax, filp->f_raend, filp->f_ralen, filp->f_rawin));
+ ssize_t ret;
/* note: i_binary=2 is for CVF-FAT. We put it here, instead of
- * umsdos_file_write_kmem, since it is also wise not to compress symlinks
- * (in the unlikely event that they are > 512 bytes and can be compressed
- * FIXME: should we set it when reading symlinks too? */
+ * umsdos_file_write_kmem, since it is also wise not to compress
+ * symlinks (in the unlikely event that they are > 512 bytes and
+ * can be compressed.
+ * FIXME: should we set it when reading symlinks too?
+ */
MSDOS_I (filp->f_dentry->d_inode)->i_binary = 2;
+ set_fs (KERNEL_DS);
ret = fat_file_write (filp, buf, count, &filp->f_pos);
- Printk ((KERN_DEBUG "fat_file_write returned with %ld!\n", (long int) ret));
-
set_fs (old_fs);
+ if (ret < 0) {
+ printk(KERN_WARNING "umsdos_file_write: ret=%d\n", ret);
+ goto out;
+ }
+#ifdef UMSDOS_PARANOIA
+if (ret != count)
+printk(KERN_WARNING "umsdos_file_write: count=%u, ret=%u\n", count, ret);
+#endif
+out:
return ret;
}
@@ -125,9 +87,8 @@ ssize_t umsdos_file_write_kmem (struct file *filp,
const char *buf,
size_t count)
{
- int ret;
+ ssize_t ret;
- Printk ((KERN_DEBUG " STARTED WRITE_KMEM /mn/\n"));
ret = umsdos_file_write_kmem_real (filp, buf, count);
return ret;
}
@@ -166,7 +127,6 @@ ssize_t umsdos_emd_dir_write ( struct file *filp,
Printk (("umsdos_emd_dir_write /mn/: calling write_kmem with %p, %p, %d, %Ld\n",
filp, buf, count, filp->f_pos));
written = umsdos_file_write_kmem (filp, buf, count);
- Printk (("umsdos_emd_dir_write /mn/: write_kmem returned\n"));
#ifdef __BIG_ENDIAN
d->nlink = le16_to_cpu (d->nlink);
@@ -179,13 +139,13 @@ filp, buf, count, filp->f_pos));
d->mode = le16_to_cpu (d->mode);
#endif
-#if UMS_DEBUG
+#ifdef UMSDOS_PARANOIA
if (written != count)
printk(KERN_ERR "umsdos_emd_dir_write: ERROR: written (%d) != count (%d)\n",
written, count);
#endif
- return written != count ? -EIO : 0;
+ return (written != count) ? -EIO : 0;
}
@@ -199,9 +159,7 @@ written, count);
ssize_t umsdos_emd_dir_read (struct file *filp, char *buf, size_t count)
{
- long int ret = 0;
- int sizeread;
-
+ ssize_t sizeread, ret = 0;
#ifdef __BIG_ENDIAN
struct umsdos_dirent *d = (struct umsdos_dirent *) buf;
@@ -211,8 +169,9 @@ ssize_t umsdos_emd_dir_read (struct file *filp, char *buf, size_t count)
filp->f_flags = 0;
sizeread = umsdos_file_read_kmem (filp, buf, count);
if (sizeread != count) {
-printk ("UMSDOS: problem with EMD file: can't read pos = %Ld (%d != %d)\n",
-filp->f_pos, sizeread, count);
+ printk (KERN_WARNING
+ "UMSDOS: EMD problem, pos=%Ld, count=%d, read=%d\n",
+ filp->f_pos, count, sizeread);
ret = -EIO;
}
#ifdef __BIG_ENDIAN
@@ -226,24 +185,27 @@ filp->f_pos, sizeread, count);
d->mode = le16_to_cpu (d->mode);
#endif
return ret;
-
}
/*
- * Create the EMD dentry for a directory.
+ * Lookup the EMD dentry for a directory.
+ *
+ * Note: the caller must hold a lock on the parent directory.
*/
struct dentry *umsdos_get_emd_dentry(struct dentry *parent)
{
struct dentry *demd;
- demd = umsdos_lookup_dentry (parent, UMSDOS_EMD_FILE,
- UMSDOS_EMD_NAMELEN);
+ demd = umsdos_lookup_dentry(parent, UMSDOS_EMD_FILE,
+ UMSDOS_EMD_NAMELEN, 1);
return demd;
}
/*
* Check whether a directory has an EMD file.
+ *
+ * Note: the caller must hold a lock on the parent directory.
*/
int umsdos_have_emd(struct dentry *dir)
{
@@ -260,37 +222,38 @@ int umsdos_have_emd(struct dentry *dir)
/*
* Create the EMD file for a directory if it doesn't
- * already exist. Returns 0 or and error code.
+ * already exist. Returns 0 or an error code.
+ *
+ * Note: the caller must hold a lock on the parent directory.
*/
int umsdos_make_emd(struct dentry *parent)
{
struct dentry *demd = umsdos_get_emd_dentry(parent);
- struct inode *inode;
int err = PTR_ERR(demd);
- if (IS_ERR(demd))
+ if (IS_ERR(demd)) {
+ printk("umsdos_make_emd: can't get dentry in %s, err=%d\n",
+ parent->d_name.name, err);
goto out;
+ }
/* already created? */
- inode = demd->d_inode;
- if (inode) {
- parent->d_inode->u.umsdos_i.i_emd_dir = inode->i_ino;
- err = 0;
- goto out_dput;
- }
+ err = 0;
+ if (demd->d_inode)
+ goto out_set;
-printk("umsdos_make_emd: creating %s/%s\n",
-parent->d_name.name, demd->d_name.name);
+Printk(("umsdos_make_emd: creating EMD %s/%s\n",
+parent->d_name.name, demd->d_name.name));
err = msdos_create(parent->d_inode, demd, S_IFREG | 0777);
if (err) {
- printk (KERN_WARNING "UMSDOS: Can't create EMD file\n");
+ printk (KERN_WARNING
+ "umsdos_make_emd: create %s/%s failed, err=%d\n",
+ parent->d_name.name, demd->d_name.name, err);
goto out_dput;
}
- inode = demd->d_inode;
- parent->d_inode->u.umsdos_i.i_emd_dir = inode->i_ino;
- /* Disable UMSDOS_notify_change() for EMD file */
- inode->u.umsdos_i.i_emd_owner = 0xffffffff;
+out_set:
+ parent->d_inode->u.umsdos_i.i_emd_dir = demd->d_inode->i_ino;
out_dput:
dput(demd);
@@ -300,92 +263,6 @@ out:
/*
- * Locate the EMD file in a directory.
- *
- * Return NULL if error, dir->u.umsdos_i.emd_inode if OK.
- * Caller must iput() returned inode when finished with it!
- * Note: deprecated; get rid of this soon!
- */
-
-struct inode *umsdos_emd_dir_lookup (struct inode *dir, int creat)
-{
- struct inode *ret = NULL;
- struct dentry *d_dir=NULL, *dlook=NULL;
- int rv;
-
- Printk ((KERN_DEBUG "Entering umsdos_emd_dir_lookup\n"));
- if (!dir) {
- printk (KERN_CRIT "umsdos_emd_dir_lookup: FATAL, dir=NULL!\n");
- goto out;
- }
- check_inode (dir);
-
- if (dir->u.umsdos_i.i_emd_dir != 0) {
- ret = iget (dir->i_sb, dir->u.umsdos_i.i_emd_dir);
- Printk (("umsdos_emd_dir_lookup: deja trouve %ld %p\n",
- dir->u.umsdos_i.i_emd_dir, ret));
- goto out;
- }
-
- PRINTK ((KERN_DEBUG "umsdos /mn/: Looking for %.*s -",
- UMSDOS_EMD_NAMELEN, UMSDOS_EMD_FILE));
-
- d_dir = geti_dentry (dir);
- if (!d_dir) {
-printk("UMSDOS: flaky i_dentry hack failed\n");
- goto out;
- }
- dlook = creat_dentry (UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN, NULL, d_dir);
- if (!dlook)
- goto out;
- rv = umsdos_real_lookup (dir, dlook);
-
- PRINTK ((KERN_DEBUG "-returned %d\n", rv));
- Printk ((KERN_INFO "emd_dir_lookup "));
-
- ret = dlook->d_inode;
- if (ret) {
- Printk (("Found --linux "));
- dir->u.umsdos_i.i_emd_dir = ret->i_ino;
- ret->i_count++; /* we'll need the inode */
- check_inode (ret);
- } else if (creat) {
- int code;
-
- Printk ((" * ERROR * /mn/: creat not yet implemented? not fixed? "));
- Printk (("avant create "));
-
- check_inode (ret);
- code = compat_msdos_create (dir, UMSDOS_EMD_FILE,
- UMSDOS_EMD_NAMELEN,
- S_IFREG | 0777, &ret);
- check_inode (ret);
- Printk (("Creat EMD code %d ret %p ", code, ret));
- if (ret != NULL) {
- Printk ((" ino=%lu", ret->i_ino));
- dir->u.umsdos_i.i_emd_dir = ret->i_ino;
- } else {
- printk (KERN_WARNING "UMSDOS: Can't create EMD file\n");
- }
- }
- dput(dlook);
-
- if (ret != NULL) {
- /* Disable UMSDOS_notify_change() for EMD file */
- ret->u.umsdos_i.i_emd_owner = 0xffffffff;
- }
-
-out:
-#if UMS_DEBUG
- Printk ((KERN_DEBUG "umsdos_emd_dir_lookup returning %p /mn/\n", ret));
- if (ret != NULL)
- Printk ((KERN_DEBUG " returning ino=%lu\n", ret->i_ino));
-#endif
- return ret;
-}
-
-
-/*
* Read an entry from the EMD file.
* Support variable length record.
* Return -EIO if error, 0 if OK.
@@ -425,6 +302,8 @@ Printk (("umsdos_emd_dir_readentry /mn/: returning len=%d,name=%.*s\n",
/*
* Write an entry in the EMD file.
* Return 0 if OK, -EIO if some error.
+ *
+ * Note: the caller must hold a lock on the parent directory.
*/
static int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
int free_entry)
@@ -443,14 +322,15 @@ static int umsdos_writeentry (struct dentry *parent, struct umsdos_info *info,
/* make sure there's an EMD file */
ret = -EIO;
if (!emd_dentry->d_inode) {
-printk("umsdos_writeentry: no EMD file in %s/%s\n",
-parent->d_parent->d_name.name, parent->d_name.name);
+ printk(KERN_WARNING
+ "umsdos_writeentry: no EMD file in %s/%s\n",
+ parent->d_parent->d_name.name, parent->d_name.name);
goto out_dput;
}
if (free_entry) {
/* #Specification: EMD file / empty entries
- * Unused entry in the EMD file are identified
+ * Unused entries in the EMD file are identified
* by the name_len field equal to 0. However to
* help future extension (or bug correction :-( ),
* empty entries are filled with 0.
@@ -506,6 +386,8 @@ struct find_buffer {
* Unread bytes are simply moved to the beginning.
*
* Return -ENOENT if EOF, 0 if OK, a negative error code if any problem.
+ *
+ * Note: the caller must hold a lock on the parent directory.
*/
static int umsdos_fillbuf (struct find_buffer *buf)
@@ -556,6 +438,7 @@ static int umsdos_fillbuf (struct find_buffer *buf)
* All this to say that umsdos_writeentry must be called after this
* function since it relies on the f_pos field of info.
*
+ * Note: the caller must hold a lock on the parent directory.
*/
/* #Specification: EMD file structure
* The EMD file uses a fairly simple layout. It is made of records
@@ -662,6 +545,8 @@ demd->d_parent->d_name.name, demd->d_name.name, emd_dir));
}
}
}
+Printk(("umsdos_find: ready to mangle %s, len=%d, pos=%ld\n",
+entry->name, entry->name_len, (long)info->f_pos));
umsdos_manglename (info);
out_dput:
@@ -795,8 +680,8 @@ int umsdos_isempty (struct dentry *dentry)
out_dput:
dput(demd);
out:
-printk("umsdos_isempty: checked %s/%s, empty=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, ret);
+Printk(("umsdos_isempty: checked %s/%s, empty=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, ret));
return ret;
}
@@ -805,11 +690,11 @@ dentry->d_parent->d_name.name, dentry->d_name.name, ret);
* Locate an entry in a EMD directory.
* Return 0 if OK, error code if not, generally -ENOENT.
*
- * does not change i_count
+ * expect argument:
+ * 0: anything
+ * 1: file
+ * 2: directory
*/
-/* 0: anything */
-/* 1: file */
-/* 2: directory */
int umsdos_findentry (struct dentry *parent, struct umsdos_info *info,
int expect)
@@ -820,14 +705,16 @@ int umsdos_findentry (struct dentry *parent, struct umsdos_info *info,
if (ret)
goto out;
- if (expect != 0) {
- if (S_ISDIR (info->entry.mode)) {
- if (expect != 2)
- ret = -EISDIR;
- } else if (expect == 2) {
+ switch (expect) {
+ case 1:
+ if (S_ISDIR (info->entry.mode))
+ ret = -EISDIR;
+ break;
+ case 2:
+ if (!S_ISDIR (info->entry.mode))
ret = -ENOTDIR;
- }
}
+
out:
Printk (("umsdos_findentry: returning %d\n", ret));
return ret;