Commit 5bdbe23a authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.25pre3

parent a3b4d222
......@@ -903,6 +903,8 @@ S: Maintained
UDF FILESYSTEM
P: Ben Fennema
M: bfennema@falcon.csc.calpoly.edu
P: Dave Boynton
M: dave@trylinux.com
L: linux_udf@hootie.lvld.hp.com
W: http://www.trylinux.com/projects/udf/index.html
S: Maintained
......
This diff is collapsed.
/*
* cycx_main.c Cyclades Cyclom X Multiprotocol WAN Link Driver. Main module.
* cycx_main.c Cyclades Cyclom 2X WAN Link Driver. Main module.
*
* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
......@@ -40,7 +40,7 @@
#ifdef MODULE
MODULE_AUTHOR("Arnaldo Carvalho de Melo");
MODULE_DESCRIPTION("Cyclades Sync Cards Driver.");
MODULE_DESCRIPTION("Cyclom 2X Sync Card Driver.");
#endif
/* Defines & Macros */
......@@ -73,7 +73,7 @@ static void cycx_isr (int irq, void *dev_id, struct pt_regs *regs);
/* private data */
static char drvname[] = "cyclomx";
static char fullname[] = "CYCLOM X(tm) Multiprotocol Driver";
static char fullname[] = "CYCLOM 2X(tm) Sync Card Driver";
static char copyright[] = "(c) 1998, 1999 Arnaldo Carvalho de Melo";
static int ncards = CONFIG_CYCLOMX_CARDS;
static cycx_t *card_array = NULL; /* adapter data space */
......@@ -214,7 +214,6 @@ static int setup (wan_device_t *wandev, wandev_conf_t *conf)
card->hw.irq = (conf->irq == 9) ? 2 : conf->irq;
card->hw.dpmbase = conf->maddr;
card->hw.dpmsize = CYCX_WINDOWSIZE;
card->hw.type = conf->hw_opt[0];
card->hw.fwid = CFID_X25_2X;
card->lock = SPIN_LOCK_UNLOCKED;
#if LINUX_VERSION_CODE >= 0x020300
......@@ -234,9 +233,7 @@ static int setup (wan_device_t *wandev, wandev_conf_t *conf)
wandev->dma = wandev->ioport = 0;
wandev->maddr = (unsigned long*)card->hw.dpmbase;
wandev->msize = card->hw.dpmsize;
wandev->hw_opt[0] = card->hw.type;
wandev->hw_opt[1] = card->hw.pclk;
wandev->hw_opt[2] = card->hw.memory;
wandev->hw_opt[2] = 0;
wandev->hw_opt[3] = card->hw.fwid;
/* Protocol-specific initialization */
......@@ -251,7 +248,6 @@ static int setup (wan_device_t *wandev, wandev_conf_t *conf)
}
if (err) {
cycx_down(&card->hw);
free_irq(irq, card);
return err;
}
......@@ -278,7 +274,6 @@ static int shutdown (wan_device_t *wandev)
card = wandev->private;
wandev->state = WAN_UNCONFIGURED;
cycx_down(&card->hw);
printk(KERN_INFO "%s: irq %d being freed!\n", wandev->name,wandev->irq);
free_irq(wandev->irq, card);
return 0;
......
This diff is collapsed.
......@@ -1316,7 +1316,7 @@ static int es1370_mmap(struct file *file, struct vm_area_struct *vma)
db = &s->dma_adc;
} else
return -EINVAL;
if (vma->vm_offset != 0)
if (vma->vm_pgoff != 0)
return -EINVAL;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
......@@ -1840,7 +1840,7 @@ static int es1370_mmap_dac(struct file *file, struct vm_area_struct *vma)
return -EINVAL;
if ((ret = prog_dmabuf_dac1(s)) != 0)
return ret;
if (vma->vm_offset != 0)
if (vma->vm_pgoff != 0)
return -EINVAL;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << s->dma_dac1.buforder))
......
......@@ -1894,7 +1894,7 @@ static int es1371_mmap(struct file *file, struct vm_area_struct *vma)
db = &s->dma_adc;
} else
return -EINVAL;
if (vma->vm_offset != 0)
if (vma->vm_pgoff != 0)
return -EINVAL;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
......@@ -2415,7 +2415,7 @@ static int es1371_mmap_dac(struct file *file, struct vm_area_struct *vma)
return -EINVAL;
if ((ret = prog_dmabuf_dac1(s)) != 0)
return ret;
if (vma->vm_offset != 0)
if (vma->vm_pgoff != 0)
return -EINVAL;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << s->dma_dac1.buforder))
......
......@@ -1199,7 +1199,7 @@ static int solo1_mmap(struct file *file, struct vm_area_struct *vma)
db = &s->dma_adc;
} else
return -EINVAL;
if (vma->vm_offset != 0)
if (vma->vm_pgoff != 0)
return -EINVAL;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
......
......@@ -1516,7 +1516,7 @@ static int sv_mmap(struct file *file, struct vm_area_struct *vma)
db = &s->dma_adc;
} else
return -EINVAL;
if (vma->vm_offset != 0)
if (vma->vm_pgoff != 0)
return -EINVAL;
size = vma->vm_end - vma->vm_start;
if (size > (PAGE_SIZE << db->buforder))
......
......@@ -64,7 +64,7 @@ int expand_fd_array(struct files_struct *files, int nr)
error = -EMFILE;
if (files->max_fds >= NR_OPEN || nr > NR_OPEN)
if (files->max_fds >= NR_OPEN || nr >= NR_OPEN)
goto out;
nfds = files->max_fds;
......@@ -88,7 +88,7 @@ int expand_fd_array(struct files_struct *files, int nr)
if (nfds > NR_OPEN)
nfds = NR_OPEN;
}
} while (nfds < nr);
} while (nfds <= nr);
error = -ENOMEM;
new_fds = alloc_fd_array(nfds);
......
......@@ -371,24 +371,31 @@ ncp_lookup_validate(struct dentry * dentry, int flags)
static struct page *
ncp_get_cache_page(struct inode *inode, unsigned long offset, int used)
{
struct page *page, **hash;
struct page *page_cache;
struct address_space *i_data = &inode->i_data;
struct page *new_page, *page, **hash;
hash = page_hash(&inode->i_data, offset);
page = __find_lock_page(&inode->i_data, offset, hash);
hash = page_hash(i_data, offset);
page = __find_lock_page(i_data, offset, hash);
if (used || page)
return page;
page_cache = page_cache_alloc();
if (page_cache) {
page = page_cache;
if (add_to_page_cache_unique(page, &inode->i_data, offset, hash)) {
page_cache_release(page);
page = NULL;
page_cache_free(page_cache);
new_page = page_cache_alloc();
if (!new_page)
return NULL;
for (;;) {
page = new_page;
if (!add_to_page_cache_unique(page, i_data, offset, hash))
break;
page_cache_release(page);
page = __find_lock_page(i_data, offset, hash);
if (page) {
page_cache_free(new_page);
break;
}
}
return page;
}
......@@ -460,6 +467,29 @@ ncp_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
return NULL;
}
static time_t ncp_obtain_mtime(struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
struct inode *parent = dentry->d_parent->d_inode;
struct ncp_server *server = NCP_SERVER(inode);
struct nw_info_struct i;
int len = dentry->d_name.len;
__u8 __name[len + 1];
if (!ncp_conn_valid(server) ||
(inode == inode->i_sb->s_root->d_inode) ||
ncp_is_server_root(parent))
return 0;
memcpy(__name, dentry->d_name.name, len);
io2vol(server, __name, !ncp_preserve_case(parent));
if (ncp_obtain_info(server, parent, __name, &i))
return 0;
return ncp_date_dos2unix(le16_to_cpu(i.modifyTime),
le16_to_cpu(i.modifyDate));
}
static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
struct dentry *dentry = filp->f_dentry;
......@@ -497,36 +527,31 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
page = ncp_get_cache_page(inode, 0, 0);
if (!page)
goto read_really;
ctl.cache = cache = (union ncp_dir_cache *) page_address(page);
ctl.head = cache->head;
if (!Page_Uptodate(page) || !ctl.head.eof)
goto init_cache;
if ((filp->f_pos == 2) &&
(jiffies - ctl.head.time >= NCP_MAX_AGE(server)))
/* Test, whether inode is changed. */
/* if (...) */
if (filp->f_pos == 2) {
time_t mtime;
if (jiffies - ctl.head.time >= NCP_MAX_AGE(server))
goto init_cache;
mtime = ncp_obtain_mtime(dentry);
if ((!mtime) || (mtime != ctl.head.mtime))
goto init_cache;
/* Todo, if inode is unchanged? */
/* else {
ncp_renew_dentries(dentry);
ctl.head.time = jiffies;
} */
}
if (filp->f_pos > ctl.head.end)
goto finished;
/*
* Should we check the complete cache before using?
* If we have big dirs, it can take a long time.
*/
ctl.fpos = filp->f_pos + (NCP_DIRCACHE_START - 2);
ctl.ofs = ctl.fpos / NCP_DIRCACHE_SIZE;
ctl.idx = ctl.fpos % NCP_DIRCACHE_SIZE;
for (;;) {
if (ctl.ofs != 0) {
ctl.page = ncp_get_cache_page(inode, ctl.ofs, 1);
......@@ -540,7 +565,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
while (ctl.idx < NCP_DIRCACHE_SIZE) {
struct dentry *dent;
int res;
dent = ncp_dget_fpos(ctl.cache->dentry[ctl.idx],
dentry, filp->f_pos);
if (!dent)
......@@ -574,6 +599,7 @@ static int ncp_readdir(struct file *filp, void *dirent, filldir_t filldir)
ctl.cache = cache;
init_cache:
ncp_invalidate_dircache_entries(dentry);
ctl.head.mtime = ncp_obtain_mtime(dentry);
ctl.head.time = jiffies;
ctl.head.eof = 0;
ctl.fpos = 2;
......
......@@ -223,15 +223,16 @@ ncp_invalidate_dircache_entries(struct dentry *parent)
}
struct ncp_cache_head {
unsigned long time; /* cache age */
unsigned long end; /* last valid fpos in cache */
int eof;
time_t mtime;
unsigned long time; /* cache age */
unsigned long end; /* last valid fpos in cache */
int eof;
};
#define NCP_DIRCACHE_SIZE ((int)(PAGE_CACHE_SIZE/sizeof(struct dentry *)))
union ncp_dir_cache {
struct ncp_cache_head head;
struct dentry *dentry[NCP_DIRCACHE_SIZE];
struct ncp_cache_head head;
struct dentry *dentry[NCP_DIRCACHE_SIZE];
};
#define NCP_FIRSTCACHE_SIZE ((int)((NCP_DIRCACHE_SIZE * \
......
......@@ -1200,12 +1200,12 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *old_inode = old_dentry->d_inode;
struct inode *new_inode = new_dentry->d_inode;
struct dentry *dentry = NULL;
int error, rehash = 0, update = 1;
int error, rehash = 0;
dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n",
old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
new_dentry->d_count);
old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
new_dentry->d_parent->d_name.name, new_dentry->d_name.name,
new_dentry->d_count);
/*
* First check whether the target is busy ... we can't
......@@ -1238,21 +1238,16 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
/* dentry still busy? */
if (new_dentry->d_count > 1) {
#ifdef NFS_PARANOIA
printk("nfs_rename: target %s/%s busy, d_count=%d\n",
new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count);
printk("nfs_rename: target %s/%s busy, d_count=%d\n",
new_dentry->d_parent->d_name.name,
new_dentry->d_name.name,
new_dentry->d_count);
#endif
goto out;
}
}
/*
* Check for within-directory rename ... no complications.
*/
if (new_dir == old_dir)
goto do_rename;
/*
* Cross-directory move ...
*
* ... prune child dentries and writebacks if needed.
*/
if (old_dentry->d_count > 1) {
......@@ -1260,40 +1255,26 @@ new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count);
shrink_dcache_parent(old_dentry);
}
/*
* Now check the use counts ... we can't safely do the
* rename unless we can drop the dentries first.
*/
if (old_dentry->d_count > 1) {
#ifdef NFS_PARANOIA
printk("nfs_rename: old dentry %s/%s busy, d_count=%d\n",
old_dentry->d_parent->d_name.name,old_dentry->d_name.name,old_dentry->d_count);
#endif
goto out;
}
if (new_dentry->d_count > 1 && new_inode) {
#ifdef NFS_PARANOIA
printk("nfs_rename: new dentry %s/%s busy, d_count=%d\n",
new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count);
printk("nfs_rename: new dentry %s/%s busy, d_count=%d\n",
new_dentry->d_parent->d_name.name,
new_dentry->d_name.name,
new_dentry->d_count);
#endif
goto out;
}
d_drop(old_dentry);
update = 0;
do_rename:
/*
* To prevent any new references to the target during the rename,
* we unhash the dentry and free the inode in advance.
*/
if (!list_empty(&new_dentry->d_hash)) {
d_drop(new_dentry);
rehash = update;
rehash = 1;
}
if (new_inode) {
if (new_inode)
d_delete(new_dentry);
}
invalidate_inode_pages(new_dir);
nfs_flush_dircache(new_dir);
......@@ -1302,13 +1283,14 @@ new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count);
error = nfs_proc_rename(NFS_DSERVER(old_dentry),
NFS_FH(old_dentry->d_parent), old_dentry->d_name.name,
NFS_FH(new_dentry->d_parent), new_dentry->d_name.name);
if (!error && !S_ISDIR(old_inode->i_mode)) {
/* Update the dcache if needed */
if (rehash)
d_add(new_dentry, NULL);
if (update)
d_move(old_dentry, new_dentry);
}
NFS_CACHEINV(old_dir);
NFS_CACHEINV(new_dir);
/* Update the dcache if needed */
if (rehash)
d_add(new_dentry, NULL);
if (!error && !S_ISDIR(old_inode->i_mode))
d_move(old_dentry, new_dentry);
out:
/* new dentry created? */
......
......@@ -719,7 +719,7 @@ int get_unused_fd(void)
* Check whether we need to expand the fd array.
*/
if (fd >= files->max_fds) {
error = expand_fd_array(files, 0);
error = expand_fd_array(files, fd);
if (!error) {
error = -EMFILE;
goto repeat;
......
......@@ -1025,14 +1025,14 @@ asmlinkage long sys_mount(char * dev_name, char * dir_name, char * type,
struct dentry * dentry = NULL;
struct inode * inode = NULL;
kdev_t dev;
int retval = -EPERM;
int retval;
unsigned long flags = 0;
unsigned long page = 0;
struct file dummy; /* allows read-write or read-only flag */
lock_kernel();
if (!capable(CAP_SYS_ADMIN))
goto out;
return -EPERM;
lock_kernel();
if ((new_flags &
(MS_MGC_MSK | MS_REMOUNT)) == (MS_MGC_VAL | MS_REMOUNT)) {
retval = copy_mount_options (data, &page);
......
......@@ -402,7 +402,7 @@ int udf_new_block(const struct inode * inode, Uint16 partition, Uint32 goal, int
got_block:
newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) -
(group_start << 3);
(sizeof(struct SpaceBitmapDesc) << 3);
tmp = udf_get_pblock(sb, newblock, partition, 0);
if (!udf_clear_bit(bit, bh->b_data))
......@@ -412,16 +412,6 @@ int udf_new_block(const struct inode * inode, Uint16 partition, Uint32 goal, int
}
mark_buffer_dirty(bh, 1);
if (!(bh = getblk(sb->s_dev, tmp, sb->s_blocksize)))
{
udf_debug("cannot get block %d\n", tmp);
unlock_super(sb);
return 0;
}
memset(bh->b_data, 0, sb->s_blocksize);
mark_buffer_uptodate(bh, 1);
mark_buffer_dirty(bh, 1);
udf_release_data(bh);
if (UDF_SB_LVIDBH(sb))
{
......
......@@ -180,7 +180,7 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
&bloc, &extoffset, &eloc, &elen, &offset, &bh) == EXTENT_RECORDED_ALLOCATED)
{
block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
if (++offset < (elen >> dir->i_sb->s_blocksize_bits))
if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
{
if (UDF_I_ALLOCTYPE(dir) == ICB_FLAG_AD_SHORT)
extoffset -= sizeof(short_ad);
......@@ -207,8 +207,6 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
filp->f_pos = nf_pos;
fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &offset, &bh);
liu = le16_to_cpu(cfi.lengthOfImpUse);
lfi = cfi.lengthFileIdent;
if (!fi)
{
......@@ -219,6 +217,9 @@ do_udf_readdir(struct inode * dir, struct file *filp, filldir_t filldir, void *d
return 1;
}
liu = le16_to_cpu(cfi.lengthOfImpUse);
lfi = cfi.lengthFileIdent;
if (fibh.sbh == fibh.ebh)
nameptr = fi->fileIdent + liu;
else
......
......@@ -112,7 +112,7 @@ udf_fileident_read(struct inode *dir, int *nf_pos,
(*offset) ++;
if (*offset >= (elen >> dir->i_sb->s_blocksize_bits))
if ((*offset << dir->i_sb->s_blocksize_bits) >= elen)
*offset = 0;
else
*extoffset = lextoffset;
......@@ -154,7 +154,7 @@ udf_fileident_read(struct inode *dir, int *nf_pos,
(*offset) ++;
if (*offset >= (elen >> dir->i_sb->s_blocksize_bits))
if ((*offset << dir->i_sb->s_blocksize_bits) >= elen)
*offset = 0;
else
*extoffset = lextoffset;
......
......@@ -213,6 +213,8 @@ static ssize_t udf_file_write(struct file * file, const char * buf,
if ((bh = udf_expand_adinicb(inode, &i, 0, &err)))
udf_release_data(bh);
else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
return err;
}
retval = generic_file_write(file, buf, count, ppos, block_write_partial_page);
......@@ -294,7 +296,9 @@ static ssize_t udf_file_read_adinicb(struct file * filp, char * buf,
if (!copy_to_user(buf, bh->b_data + pos, left))
*loff += left;
else
return -EFAULT;
left = -EFAULT;
udf_release_data(bh);
return left;
}
......@@ -336,11 +340,11 @@ static ssize_t udf_file_read_adinicb(struct file * filp, char * buf,
int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
int result=-1;
int size;
int result = -1;
struct buffer_head *bh = NULL;
struct FileEntry *fe;
Uint16 ident;
long_ad eaicb;
Uint8 *ea = NULL;
if ( permission(inode, MAY_READ) != 0 )
{
......@@ -368,26 +372,42 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
/* ok, we need to read the inode */
bh = udf_read_ptagged(inode->i_sb, UDF_I_LOCATION(inode), 0, &ident);
if (!bh || ident != TID_FILE_ENTRY)
if (!bh || (ident != TID_FILE_ENTRY && ident != TID_EXTENDED_FILE_ENTRY))
{
udf_debug("bread failed (ino=%ld) or ident (%d) != TID_FILE_ENTRY",
udf_debug("bread failed (ino=%ld) or ident (%d) != TID_(EXTENDED_)FILE_ENTRY",
inode->i_ino, ident);
return -EFAULT;
}
fe = (struct FileEntry *)bh->b_data;
size = le32_to_cpu(fe->lengthExtendedAttr);
if (UDF_I_EXTENDED_FE(inode) == 0)
{
struct FileEntry *fe;
fe = (struct FileEntry *)bh->b_data;
eaicb = fe->extendedAttrICB;
if (UDF_I_LENEATTR(inode))
ea = fe->extendedAttr;
}
else
{
struct ExtendedFileEntry *efe;
efe = (struct ExtendedFileEntry *)bh->b_data;
eaicb = efe->extendedAttrICB;
if (UDF_I_LENEATTR(inode))
ea = efe->extendedAttr;
}
switch (cmd)
{
case UDF_GETEASIZE:
if ( (result = verify_area(VERIFY_WRITE, (char *)arg, 4)) == 0)
result= put_user(size, (int *)arg);
result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
break;
case UDF_GETEABLOCK:
if ( (result = verify_area(VERIFY_WRITE, (char *)arg, size)) == 0)
result= copy_to_user((char *)arg, fe->extendedAttr, size);
if ( (result = verify_area(VERIFY_WRITE, (char *)arg, UDF_I_LENEATTR(inode))) == 0)
result = copy_to_user((char *)arg, ea, UDF_I_LENEATTR(inode));
break;
default:
......
......@@ -106,18 +106,48 @@ void udf_delete_inode(struct inode * inode)
void udf_discard_prealloc(struct inode * inode)
{
#ifdef UDF_PREALLOCATE
#if 0
unsigned short total;
lb_addr loc = UDF_I_LOCATION(inode);
lb_addr bloc, eloc;
Uint32 extoffset, elen, nelen, offset, adsize = 0;
struct buffer_head *bh = NULL;
if (UDF_I_PREALLOC_COUNT(inode))
if ((inode->i_size > 0) &&
(inode_bmap(inode, (inode->i_size-1) >> inode->i_sb->s_blocksize_bits,
&bloc, &extoffset, &eloc, &elen, &offset, &bh) ==
EXTENT_RECORDED_ALLOCATED))
{
total = UDF_I_PREALLOC_COUNT(inode);
UDF_I_PREALLOC_COUNT(inode) = 0;
loc.logicalBlockNum = UDF_I_PREALLOC_BLOCK(inode);
udf_free_blocks(inode, loc, 0, total);
if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_SHORT)
adsize = sizeof(short_ad);
else if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_LONG)
adsize = sizeof(long_ad);
else
{
udf_release_data(bh);
return;
}
nelen = (EXTENT_RECORDED_ALLOCATED << 30) |
((((elen - 1) & ~(inode->i_sb->s_blocksize - 1)) |
((inode->i_size - 1) & (inode->i_sb->s_blocksize - 1))) + 1);
if (nelen != ((EXTENT_RECORDED_ALLOCATED << 30) | elen))
{
extoffset -= adsize;
udf_write_aext(inode, bloc, &extoffset, eloc, nelen, &bh, 1);
}
if (udf_next_aext(inode, &bloc, &extoffset, &eloc, &elen, &bh, 0) ==
EXTENT_NOT_RECORDED_ALLOCATED)
{
udf_free_blocks(inode, eloc, 0, elen >> inode->i_sb->s_blocksize_bits);
memset(&eloc, 0x00, sizeof(lb_addr));
udf_write_aext(inode, bloc, &extoffset, eloc, 0, &bh, 1);
UDF_I_LENALLOC(inode) -= adsize;
udf_write_inode(inode);
}
udf_release_data(bh);
}
#endif
else if (bh)
udf_release_data(bh);
#endif
}
......@@ -144,6 +174,9 @@ struct buffer_head * udf_expand_adinicb(struct inode *inode, int *block, int isd
{
UDF_I_EXT0OFFS(inode) = 0;
UDF_I_ALLOCTYPE(inode) = ICB_FLAG_AD_LONG;
mark_inode_dirty(inode);
if (inode->i_op == &udf_file_inode_operations_adinicb)
inode->i_op = &udf_file_inode_operations;
return NULL;
}
......@@ -208,6 +241,7 @@ struct buffer_head * udf_expand_adinicb(struct inode *inode, int *block, int isd
memset(sbh->b_data + udf_file_entry_alloc_offset(inode),
0, UDF_I_LENALLOC(inode));
memset(&newad, 0x00, sizeof(long_ad));
newad.extLength = UDF_I_EXT0LEN(inode) = inode->i_size;
newad.extLocation.logicalBlockNum = *block;
newad.extLocation.partitionReferenceNum = UDF_I_LOCATION(inode).partitionReferenceNum;
......@@ -248,7 +282,7 @@ struct buffer_head * udf_getblk(struct inode * inode, long block,
bh = getblk(dummy.b_dev, dummy.b_blocknr, inode->i_sb->s_blocksize);
if (buffer_new(&dummy))
{
memset(bh->b_data, 0, inode->i_sb->s_blocksize);
memset(bh->b_data, 0x00, inode->i_sb->s_blocksize);
mark_buffer_uptodate(bh, 1);
mark_buffer_dirty(bh, 1);
}
......@@ -340,6 +374,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
if (pbh != cbh)
{
udf_release_data(pbh);
pbh = cbh;
atomic_inc(&cbh->b_count);
pbloc = cbloc;
}
......@@ -462,7 +497,6 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
UDF_I_LOCATION(inode).partitionReferenceNum, goal, err)))
{
udf_release_data(pbh);
udf_release_data(cbh);
*err = -ENOSPC;
return NULL;
}
......@@ -488,7 +522,7 @@ static struct buffer_head * inode_getblk(struct inode * inode, long block,
udf_release_data(pbh);
if (c == 0 || c == 1)
if (pextoffset == udf_file_entry_alloc_offset(inode))
{
UDF_I_EXT0LEN(inode) = laarr[0].extLength;
UDF_I_EXT0LOC(inode) = laarr[0].extLocation;
......@@ -889,7 +923,8 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
{
struct FileEntry *fe;
struct ExtendedFileEntry *efe;
time_t convtime;
time_t convtime;
long convtime_usec;
int offset, alen;
fe = (struct FileEntry *)bh->b_data;
......@@ -940,21 +975,33 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) <<
(inode->i_sb->s_blocksize_bits - 9);
if ( udf_stamp_to_time(&convtime, lets_to_cpu(fe->modificationTime)) )
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(fe->modificationTime)) )
{
inode->i_mtime = convtime;
UDF_I_UMTIME(inode) = convtime_usec;
inode->i_ctime = convtime;
UDF_I_UCTIME(inode) = convtime_usec;
}
else
{
inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
UDF_I_UMTIME(inode) = 0;
inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
UDF_I_UCTIME(inode) = 0;
}
if ( udf_stamp_to_time(&convtime, lets_to_cpu(fe->accessTime)) )
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(fe->accessTime)) )
{
inode->i_atime = convtime;
UDF_I_UATIME(inode) = convtime_usec;
}
else
{
inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
UDF_I_UATIME(inode) = convtime_usec;
}
UDF_I_UNIQUE(inode) = le64_to_cpu(fe->uniqueID);
UDF_I_LENEATTR(inode) = le32_to_cpu(fe->lengthExtendedAttr);
......@@ -967,20 +1014,41 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) <<
(inode->i_sb->s_blocksize_bits - 9);
if ( udf_stamp_to_time(&convtime, lets_to_cpu(efe->modificationTime)) )
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->modificationTime)) )
{
inode->i_mtime = convtime;
UDF_I_UMTIME(inode) = convtime_usec;
}
else
{
inode->i_mtime = UDF_SB_RECORDTIME(inode->i_sb);
UDF_I_UMTIME(inode) = 0;
}
if ( udf_stamp_to_time(&convtime, lets_to_cpu(efe->accessTime)) )
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->accessTime)) )
{
inode->i_atime = convtime;
UDF_I_UATIME(inode) = convtime_usec;
}
else
{
inode->i_atime = UDF_SB_RECORDTIME(inode->i_sb);
UDF_I_UATIME(inode) = 0;
}
if ( udf_stamp_to_time(&convtime, lets_to_cpu(efe->createTime)) )
if ( udf_stamp_to_time(&convtime, &convtime_usec,
lets_to_cpu(efe->createTime)) )
{
inode->i_ctime = convtime;
UDF_I_UCTIME(inode) = convtime_usec;
}
else
{
inode->i_ctime = UDF_SB_RECORDTIME(inode->i_sb);
UDF_I_UCTIME(inode) = 0;
}
UDF_I_UNIQUE(inode) = le64_to_cpu(efe->uniqueID);
UDF_I_LENEATTR(inode) = le32_to_cpu(efe->lengthExtendedAttr);
......@@ -1274,8 +1342,8 @@ udf_update_inode(struct inode *inode, int do_sync)
efe->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
efe->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
efe->uniqueID = cpu_to_le64(UDF_I_UNIQUE(inode));
efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
efe->lengthExtendedAttr = cpu_to_le32(UDF_I_LENEATTR(inode));
efe->lengthAllocDescs = cpu_to_le32(UDF_I_LENALLOC(inode));
efe->descTag.tagIdent = le16_to_cpu(TID_EXTENDED_FILE_ENTRY);
crclen = sizeof(struct ExtendedFileEntry);
}
......@@ -1764,6 +1832,8 @@ int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
return -1;
}
}
else
atomic_inc(&bh->b_count);
while ((type = udf_next_aext(inode, &bloc, &extoffset, &oeloc, &oelen, &bh, 0)) != -1)
{
......@@ -1773,6 +1843,7 @@ int udf_insert_aext(struct inode *inode, lb_addr bloc, int extoffset,
nelen = (type << 30) | oelen;
}
udf_add_aext(inode, &bloc, &extoffset, neloc, nelen, &bh, 1);
udf_release_data(bh);
return (nelen >> 30);
}
......@@ -1879,12 +1950,12 @@ int inode_bmap(struct inode *inode, int block, lb_addr *bloc, Uint32 *extoffset,
if (block < 0)
{
printk(KERN_ERR "udf: inode_bmap: block < 0\n");
return 0;
return -1;
}
if (!inode)
{
printk(KERN_ERR "udf: inode_bmap: NULL inode\n");
return 0;
return -1;
}
b_off = block << inode->i_sb->s_blocksize_bits;
......
......@@ -95,16 +95,17 @@ udf_get_last_block(kdev_t dev, int *flags)
int ret;
unsigned long lblock;
unsigned int hbsize = get_hardblocksize(dev);
unsigned int secsize = 512;
unsigned int mult = 0;
unsigned int div = 0;
if (!hbsize)
hbsize = 512;
hbsize = blksize_size[MAJOR(dev)][MINOR(dev)];
if (hbsize > blksize_size[MAJOR(dev)][MINOR(dev)])
mult = hbsize / blksize_size[MAJOR(dev)][MINOR(dev)];
else if (blksize_size[MAJOR(dev)][MINOR(dev)] > hbsize)
div = blksize_size[MAJOR(dev)][MINOR(dev)] / hbsize;
if (secsize > hbsize)
mult = secsize / hbsize;
else if (hbsize > secsize)
div = hbsize / secsize;
if (get_blkfops(MAJOR(dev))->ioctl!=NULL)
{
......@@ -138,7 +139,7 @@ udf_get_last_block(kdev_t dev, int *flags)
}
set_fs(old_fs);
if (!ret)
if (!ret && lblock)
return lblock - 1;
}
else
......
......@@ -66,28 +66,6 @@ udf64_high32(Uint64 indat)
return indat >> 32;
}
/*
* udf_stamp_to_time
*/
time_t *
udf_stamp_to_time(time_t *dest, timestamp src)
{
struct ktm tm;
if ((!dest))
return NULL;
/* this is very rough. need to find source to mktime() */
tm.tm_year=(src.year) - 1900;
tm.tm_mon=(src.month);
tm.tm_mday=(src.day);
tm.tm_hour=src.hour;
tm.tm_min=src.minute;
tm.tm_sec=src.second;
*dest = udf_converttime(&tm);
return dest;
}
uid_t udf_convert_uid(int uidin)
{
if ( uidin == -1 )
......
This diff is collapsed.
......@@ -768,18 +768,20 @@ udf_load_pvoldesc(struct super_block *sb, struct buffer_head *bh)
{
struct PrimaryVolDesc *pvoldesc;
time_t recording;
long recording_usec;
struct ustr instr;
struct ustr outstr;
pvoldesc = (struct PrimaryVolDesc *)bh->b_data;
if ( udf_stamp_to_time(&recording, lets_to_cpu(pvoldesc->recordingDateAndTime)) )
if ( udf_stamp_to_time(&recording, &recording_usec,
lets_to_cpu(pvoldesc->recordingDateAndTime)) )
{
timestamp ts;
ts = lets_to_cpu(pvoldesc->recordingDateAndTime);
udf_debug("recording time %ld, %u/%u/%u %u:%u (%x)\n",
recording, ts.year, ts.month, ts.day, ts.hour, ts.minute,
ts.typeAndTimezone);
udf_debug("recording time %ld/%ld, %04u/%02u/%02u %02u:%02u (%x)\n",
recording, recording_usec,
ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.typeAndTimezone);
UDF_SB_RECORDTIME(sb) = recording;
}
......@@ -1397,8 +1399,9 @@ udf_read_super(struct super_block *sb, void *options, int silent)
{
timestamp ts;
udf_time_to_stamp(&ts, UDF_SB_RECORDTIME(sb), 0);
udf_info("Mounting volume '%s', timestamp %u/%02u/%u %02u:%02u\n",
UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute);
udf_info("Mounting volume '%s', timestamp %04u/%02u/%02u %02u:%02u (%x)\n",
UDF_SB_VOLIDENT(sb), ts.year, ts.month, ts.day, ts.hour, ts.minute,
ts.typeAndTimezone);
}
if (!(sb->s_flags & MS_RDONLY))
udf_open_lvid(sb);
......
#ifndef __UDF_DECL_H
#define __UDF_DECL_H
#define UDF_VERSION_NOTICE "v0.8.9"
#define UDF_VERSION_NOTICE "v0.8.9.3"
#ifdef __KERNEL__
......@@ -249,7 +249,7 @@ extern Uint32 udf64_low32(Uint64);
extern Uint32 udf64_high32(Uint64);
extern time_t *udf_stamp_to_time(time_t *, timestamp);
extern time_t *udf_stamp_to_time(time_t *, long *, timestamp);
extern timestamp *udf_time_to_stamp(timestamp *, time_t, long);
extern time_t udf_converttime (struct ktm *);
......
......@@ -42,13 +42,13 @@
#define cpu_to_le32(x) (x)
#define cpu_to_le64(x) (x)
#endif
#endif /* __BYTE_ORDER == 0 */
#endif
#else /* __KERNEL__ */
#ifdef __KERNEL__
#include <linux/string.h>
#endif
#endif /* ! __KERNEL__ */
static inline lb_addr lelb_to_cpu(lb_addr in)
{
......
This diff is collapsed.
......@@ -11,13 +11,14 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
* 1999/10/23 acme cycxhw_t cleanup
* 1999/01/03 acme more judicious use of data types...
* uclong, ucchar, etc deleted, the u8, u16, u32
* types are the portable way to go.
* 1999/01/03 acme judicious use of data types... u16, u32, etc
* Dec 26, 1998 Arnaldo FIXED_BUFFERS, CONF_OFFSET,
* 1998/12/26 acme FIXED_BUFFERS, CONF_OFFSET,
* removal of cy_read{bwl}
* Aug 08, 1998 Arnaldo Initial version.
* 1998/08/08 acme Initial version.
*/
#ifndef _CYCX_DRV_H
#define _CYCX_DRV_H
......@@ -43,22 +44,19 @@
/* Adapter hardware configuration. Pointer to this structure is passed to all
* APIs. */
typedef struct cycxhw {
u32 type; /* adapter type */
u32 fwid; /* firmware ID */
int irq; /* interrupt request level */
u32 dpmbase; /* dual-port memory base */
u32 dpmsize; /* dual-port memory size */
u32 pclk; /* CPU clock rate, kHz */
u32 memory; /* memory size */
u32 reserved[5];
} cycxhw_t;
/* Function Prototypes */
extern int cycx_setup (cycxhw_t *hw, void *sfm, u32 len);
extern int cycx_down (cycxhw_t *hw);
extern int cycx_inten (cycxhw_t *hw);
extern int cycx_intr (cycxhw_t *hw);
extern int cycx_peek (cycxhw_t *hw, u32 addr, void *buf, u32 len);
extern int cycx_poke (cycxhw_t *hw, u32 addr, void *buf, u32 len);
extern int cycx_exec (u32 addr);
extern void cycx_inten (cycxhw_t *hw);
extern void cycx_intr (cycxhw_t *hw);
#endif /* _CYCX_DRV_H */
......@@ -13,6 +13,7 @@
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Florian La Roche,
* Jonathan Layes <layes@loran.com>
* Arnaldo Carvalho de Melo <acme@conectiva.com.br> ARPHRD_HWX25
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -47,6 +48,7 @@
#define ARPHRD_ADAPT 264
#define ARPHRD_ROSE 270
#define ARPHRD_X25 271 /* CCITT X.25 */
#define ARPHRD_HWX25 272 /* Boards with X.25 in firmware */
#define ARPHRD_PPP 512
#define ARPHRD_HDLC 513 /* (Cisco) HDLC */
#define ARPHRD_LAPB 516 /* LAPB */
......
......@@ -54,15 +54,23 @@
#ifdef __KERNEL__
#include <linux/types.h>
#define Uint8 __u8
#define Sint8 __s8
#define Uint16 __u16
#define Sint16 __s16
#define Uint32 __u32
#define Sint32 __s32
#define Uint64 __u64
#define Sint64 __s64
typedef Uint8 dstring;
#else
#define Uint8 unsigned char
#define Sint8 char
#define Uint16 unsigned short
#define Sint16 short
#define Uint32 unsigned int
#define Sint32 int
#define Uint64 unsigned long long
#define Sint64 long long
typedef Uint8 dstring;
#endif
......
......@@ -30,8 +30,8 @@
#define UDF_DEFAULT_PREALLOC_BLOCKS 8
#define UDF_DEFAULT_PREALLOC_DIR_BLOCKS 0
#define UDFFS_DATE "99/09/02"
#define UDFFS_VERSION "0.8.9"
#define UDFFS_DATE "99/10/29"
#define UDFFS_VERSION "0.8.9.3"
#define UDFFS_DEBUG
#ifdef UDFFS_DEBUG
......
......@@ -294,7 +294,8 @@ rpc_call_setup(struct rpc_task *task, u32 proc,
task->tk_flags |= flags;
/* Increment call count */
rpcproc_count(task->tk_client, proc)++;
if (task->tk_proc < task->tk_client->cl_maxproc)
rpcproc_count(task->tk_client, proc)++;
}
/*
......@@ -319,9 +320,14 @@ static void
call_bind(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
struct rpc_xprt *xprt = clnt->cl_xprt;
task->tk_action = call_reserve;
if (xprt->stream && !xprt->connected)
task->tk_action = call_reconnect;
else
task->tk_action = call_reserve;
task->tk_status = 0;
if (!clnt->cl_port)
rpc_getport(task, clnt);
}
......@@ -340,6 +346,7 @@ call_reserve(struct rpc_task *task)
clnt->cl_protname, clnt->cl_server,
clnt->cl_softrtry? "giving up" : "retrying");
if (!clnt->cl_softrtry) {
task->tk_action = call_bind;
rpc_delay(task, 5*HZ);
return;
}
......@@ -376,25 +383,27 @@ call_reserveresult(struct rpc_task *task)
if (task->tk_status >= 0) {
task->tk_action = call_allocate;
goto out;
} else if (task->tk_status == -EAGAIN) {
return;
}
switch (task->tk_status) {
case -EAGAIN:
case -ENOBUFS:
task->tk_timeout = task->tk_client->cl_timeout.to_resrvval;
task->tk_status = 0;
xprt_reserve(task);
goto out;
} else if (task->tk_status == -ETIMEDOUT) {
task->tk_action = call_reserve;
break;
case -ETIMEDOUT:
dprintk("RPC: task timed out\n");
task->tk_action = call_timeout;
goto out;
} else {
break;
default:
task->tk_action = NULL;
if (!task->tk_rqstp) {
printk("RPC: task has no request, exit EIO\n");
rpc_exit(task, -EIO);
}
}
if (!task->tk_rqstp) {
printk("RPC: task has no request, exit EIO\n");
rpc_exit(task, -EIO);
}
out:
return;
}
/*
......@@ -424,7 +433,7 @@ call_allocate(struct rpc_task *task)
if (!signalled()) {
xprt_release(task);
task->tk_action = call_reserve;
rpc_delay(task, HZ);
rpc_delay(task, HZ>>4);
return;
}
......@@ -477,7 +486,7 @@ call_encode(struct rpc_task *task)
printk("RPC: call_header failed, exit EIO\n");
rpc_exit(task, -EIO);
} else
if ((status = encode(req, p, task->tk_argp)) < 0) {
if (encode && (status = encode(req, p, task->tk_argp)) < 0) {
printk(KERN_WARNING "%s: can't encode arguments: %d\n",
clnt->cl_protname, -status);
rpc_exit(task, status);
......@@ -508,19 +517,16 @@ call_receive(struct rpc_task *task)
task->tk_pid, task->tk_status);
task->tk_action = call_status;
/* In case of error, evaluate status */
if (task->tk_status < 0)
return;
/* Need to ensure cleanups are performed by xprt_receive_status() */
xprt_receive(task);
/* If we have no decode function, this means we're performing
* a void call (a la lockd message passing). */
if (!rpcproc_decode(task->tk_client, task->tk_proc)) {
rpc_remove_wait_queue(task); /* remove from xprt_pending */
task->tk_action = NULL;
return;
}
xprt_receive(task);
}
/*
......@@ -530,6 +536,7 @@ static void
call_status(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
struct rpc_xprt *xprt = clnt->cl_xprt;
struct rpc_rqst *req;
int status = task->tk_status;
......@@ -538,28 +545,48 @@ call_status(struct rpc_task *task)
if (status >= 0) {
task->tk_action = call_decode;
} else if (status == -ETIMEDOUT) {
}
task->tk_status = 0;
req = task->tk_rqstp;
switch(status) {
case -ETIMEDOUT:
task->tk_action = call_timeout;
} else if (status == -EAGAIN) {
if (!(req = task->tk_rqstp))
break;
case -EAGAIN:
if (!req)
task->tk_action = call_reserve;
else if (!task->tk_buffer)
task->tk_action = call_allocate;
else if (req->rq_damaged)
else if (req->rq_damaged) {
task->tk_action = call_encode;
else
clnt->cl_stats->rpcretrans++;
} else {
task->tk_action = call_transmit;
} else if (status == -ENOTCONN) {
task->tk_action = call_reconnect;
} else if (status == -ECONNREFUSED && clnt->cl_autobind) {
task->tk_action = call_bind;
clnt->cl_port = 0;
} else {
clnt->cl_stats->rpcretrans++;
}
break;
case -ECONNREFUSED:
case -ENOTCONN:
if (clnt->cl_autobind || !clnt->cl_port) {
clnt->cl_port = 0;
task->tk_action = call_bind;
} else if (xprt->stream)
task->tk_action = call_reconnect;
else {
rpc_delay(task, 5*HZ); /* Hope it all wears off */
if (req->rq_damaged)
task->tk_action = call_encode;
else
task->tk_action = call_transmit;
clnt->cl_stats->rpcretrans++;
}
break;
default:
if (clnt->cl_chatty)
printk("%s: RPC call returned error %d\n",
clnt->cl_protname, -status);
task->tk_action = NULL;
return;
clnt->cl_protname, -status);
rpc_exit(task, status);
}
}
......@@ -600,7 +627,7 @@ call_timeout(struct rpc_task *task)
if (req)
printk("%s: server %s not responding, still trying\n",
clnt->cl_protname, clnt->cl_server);
else
else
printk("%s: task %d can't get a request slot\n",
clnt->cl_protname, task->tk_pid);
}
......@@ -610,6 +637,8 @@ call_timeout(struct rpc_task *task)
minor_timeout:
if (!clnt->cl_port) {
task->tk_action = call_bind;
} else if (clnt->cl_xprt->stream && !clnt->cl_xprt->connected) {
task->tk_action = call_reconnect;
} else if (!req) {
task->tk_action = call_reserve;
} else if (req->rq_damaged) {
......@@ -628,14 +657,12 @@ call_timeout(struct rpc_task *task)
static void
call_reconnect(struct rpc_task *task)
{
struct rpc_clnt *clnt = task->tk_client;
dprintk("RPC: %4d call_reconnect status %d\n",
task->tk_pid, task->tk_status);
if (task->tk_status == 0) {
task->tk_action = call_status;
task->tk_status = -EAGAIN;
return;
}
task->tk_client->cl_stats->netreconn++;
task->tk_action = call_reserve;
task->tk_status = 0;
clnt->cl_stats->netreconn++;
xprt_reconnect(task);
}
......@@ -685,7 +712,9 @@ call_decode(struct rpc_task *task)
}
task->tk_action = NULL;
task->tk_status = decode(req, p, task->tk_resp);
if (decode)
task->tk_status = decode(req, p, task->tk_resp);
dprintk("RPC: %4d call_decode result %d\n", task->tk_pid,
task->tk_status);
}
......@@ -714,11 +743,10 @@ call_refreshresult(struct rpc_task *task)
dprintk("RPC: %4d call_refreshresult (status %d)\n",
task->tk_pid, task->tk_status);
if (task->tk_status < 0) {
task->tk_status = -EACCES;
task->tk_action = NULL;
} else
task->tk_action = call_reserve;
if (task->tk_status < 0)
rpc_exit(task, -EACCES);
else
task->tk_action = call_bind;
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment