patch-1.3.62 linux/fs/fat/dir.c
Next file: linux/fs/fat/inode.c
Previous file: linux/drivers/scsi/st.c
Back to the patch index
Back to the overall index
- Lines: 164
- Date:
Sun Feb 11 12:39:19 1996
- Orig file:
v1.3.61/linux/fs/fat/dir.c
- Orig date:
Fri Feb 9 17:53:06 1996
diff -u --recursive --new-file v1.3.61/linux/fs/fat/dir.c linux/fs/fat/dir.c
@@ -17,6 +17,7 @@
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/ioctl.h>
+#include <linux/dirent.h>
#include <asm/segment.h>
@@ -44,30 +45,12 @@
file_fsync /* fsync */
};
-
-int fat_dir_ioctl(struct inode * inode, struct file * filp,
- unsigned int cmd, unsigned long arg)
-{
- switch (cmd) {
-#if 0
- /*
- * We want to provide an interface for Samba to be able
- * to get the short filename for a given long filename.
- * We should be able to accomplish by modifying fat_readdir
- * slightly.
- */
- case VFAT_LONGNAME_TO_SHORT:
-#endif
- default:
- return -EINVAL;
- }
-}
-
-int fat_readdir(
+int fat_readdirx(
struct inode *inode,
struct file *filp,
void *dirent,
- filldir_t filldir)
+ filldir_t filldir,
+ int both)
{
struct super_block *sb = inode->i_sb;
int ino,i,i2,last;
@@ -76,7 +59,7 @@
struct msdos_dir_entry *de;
unsigned long oldpos = filp->f_pos;
int is_long;
- char longname[256];
+ char longname[275];
unsigned char long_len = 0; /* Make compiler warning go away */
unsigned char alias_checksum = 0; /* Make compiler warning go away */
@@ -209,7 +192,7 @@
}
PRINTK(("Long filename: %s, get_new_entry: %d\n", longname, get_new_entry));
} else if (!IS_FREE(de->name) && !(de->attr & ATTR_VOLUME)) {
- char bufname[13];
+ char bufname[14];
char *ptname = bufname;
int dotoffset = 0;
@@ -258,11 +241,20 @@
ino = fat_parent_ino(inode,0);
if (!is_long) {
+ dcache_add(inode, bufname, i+dotoffset, ino);
+ if (both) {
+ bufname[i+dotoffset] = '\0';
+ }
if (filldir(dirent, bufname, i+dotoffset, oldpos, ino) < 0) {
filp->f_pos = oldpos;
break;
}
} else {
+ dcache_add(inode, longname, long_len, ino);
+ if (both) {
+ memcpy(&longname[long_len+1], bufname, i+dotoffset);
+ long_len += i+dotoffset;
+ }
if (filldir(dirent, longname, long_len, oldpos, ino) < 0) {
filp->f_pos = oldpos;
break;
@@ -278,5 +270,82 @@
ino = fat_get_entry(inode,&filp->f_pos,&bh,&de);
}
if (bh) brelse(bh);
+ return 0;
+}
+
+int fat_readdir(
+ struct inode *inode,
+ struct file *filp,
+ void *dirent,
+ filldir_t filldir)
+{
+ return fat_readdirx(inode, filp, dirent, filldir, 0);
+}
+static int vfat_ioctl_fill(
+ void * buf,
+ const char * name,
+ int name_len,
+ off_t offset,
+ ino_t ino)
+{
+ struct dirent *d1 = (struct dirent *)buf;
+ struct dirent *d2 = d1 + 1;
+ int len, slen;
+ int dotdir;
+
+ if (get_user(&d1->d_reclen) != 0) {
+ return -1;
+ }
+
+ if ((name_len == 1 && name[0] == '.') ||
+ (name_len == 2 && name[0] == '.' && name[1] == '.')) {
+ dotdir = 1;
+ len = name_len;
+ } else {
+ dotdir = 0;
+ len = strlen(name);
+ }
+ if (len != name_len) {
+ memcpy_tofs(d2->d_name, name, len);
+ put_user(0, d2->d_name + len);
+ put_user(len, &d2->d_reclen);
+ put_user(ino, &d2->d_ino);
+ put_user(offset, &d2->d_off);
+ slen = name_len - len;
+ memcpy_tofs(d1->d_name, name+len+1, slen);
+ put_user(0, d1->d_name+slen);
+ put_user(slen, &d1->d_reclen);
+ } else {
+ put_user(0, d2->d_name);
+ put_user(0, &d2->d_reclen);
+ memcpy_tofs(d1->d_name, name, len);
+ put_user(0, d1->d_name+len);
+ put_user(len, &d1->d_reclen);
+ }
+ PRINTK(("FAT d1=%p d2=%p len=%d, name_len=%d\n",
+ d1, d2, len, name_len));
+
+ return 0;
+}
+
+int fat_dir_ioctl(struct inode * inode, struct file * filp,
+ unsigned int cmd, unsigned long arg)
+{
+ /*
+ * We want to provide an interface for Samba to be able
+ * to get the short filename for a given long filename.
+ * Samba should use this ioctl instead of readdir() to
+ * get the information it needs.
+ */
+ switch (cmd) {
+ case VFAT_IOCTL_READDIR_BOTH: {
+ struct dirent *d1 = (struct dirent *)arg;
+ put_user(0, &d1->d_reclen);
+ return fat_readdirx(inode,filp,(void *)arg,vfat_ioctl_fill,1);
+ }
+ default:
+ return -EINVAL;
+ }
+
return 0;
}
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