From: Ben O. <ben...@us...> - 2002-03-01 09:15:43
|
Update of /cvsroot/njbfs/njbfs In directory usw-pr-cvs1:/tmp/cvs-serv8286 Modified Files: Tag: ben dir.c njb_usb.c njb_usb.h njbfs.h njbfs_cache.c njbfs_cache.h njbfs_dir.c njbfs_proc.h nomad.c proc.c proc.h Log Message: Ben: first pass at the NJB write cache Index: dir.c =================================================================== RCS file: /cvsroot/njbfs/njbfs/dir.c,v retrieving revision 1.3.2.2 retrieving revision 1.3.2.3 diff -C2 -d -r1.3.2.2 -r1.3.2.3 *** dir.c 24 Feb 2002 11:33:58 -0000 1.3.2.2 --- dir.c 1 Mar 2002 09:15:40 -0000 1.3.2.3 *************** *** 402,409 **** struct njbfs_sb_info *info = (struct njbfs_sb_info *) dentry->d_sb->u.generic_sbp; - char buf[NJBFS_MAXPATHLEN]; ! njbfs_get_name(dentry, buf); ! njbfs_cache_invalidate(dentry->d_parent); ! return njbfs_proc_unlink(info, buf); } --- 402,406 ---- struct njbfs_sb_info *info = (struct njbfs_sb_info *) dentry->d_sb->u.generic_sbp; ! return njbfs_proc_unlink(info, dentry); } Index: njb_usb.c =================================================================== RCS file: /cvsroot/njbfs/njbfs/njb_usb.c,v retrieving revision 1.4.2.3 retrieving revision 1.4.2.4 diff -C2 -d -r1.4.2.3 -r1.4.2.4 *** njb_usb.c 24 Feb 2002 11:33:58 -0000 1.4.2.3 --- njb_usb.c 1 Mar 2002 09:15:40 -0000 1.4.2.4 *************** *** 223,227 **** dbg("open: handshake ok"); ! /* Get disk usage */ status = njb_usb_get_disk_usage(njb, &total, &free); if (status < 0) { --- 223,227 ---- dbg("open: handshake ok"); ! /* Get disk usage */ status = njb_usb_get_disk_usage(njb, &total, &free); if (status < 0) { *************** *** 237,243 **** return -ENOSPC; } ! /** ! * Build track, write track tag, and get NJB track id as a result ! */ trackid = 0; track = njb_usb_update_track_tag(njb, fattr, &trackid); --- 237,245 ---- return -ENOSPC; } ! ! ! /** ! * Build track, write track tag, and get NJB track id as a result ! */ trackid = 0; track = njb_usb_update_track_tag(njb, fattr, &trackid); *************** *** 250,258 **** fattr->track = track; /* save track */ fattr->fileid = trackid; /* for requesting the track tag later */ ! return status; } else if (fattr->fileid > 0) { ! dbg("attempting to open '%s'..", fattr->title); /* Open for read track */ --- 252,261 ---- fattr->track = track; /* save track */ fattr->fileid = trackid; /* for requesting the track tag later */ ! return status; } else if (fattr->fileid > 0) { ! printk("attempting to open '%s' (%d)..", fattr->title, ! fattr->fileid); /* Open for read track */ *************** *** 348,365 **** } - if (fattr->fileid == 0) { - - /* update library counter */ - dbg("close: updating lib counter"); - status = njb_usb_update_library_counter(njb); - if (status < 0) { - err - ("close: updating lib count error, status = %d, ", - status); - return -EPROTO; - } - } - - njb->isopen = 0; dbg("close: jukebox closed"); --- 351,354 ---- *************** *** 523,526 **** --- 512,516 ---- ("write: bulk write error, actual_length = %d, status = %d", actual_length, status); + return status; } if (actual_length < count) { *************** *** 535,538 **** --- 525,529 ---- err("write: can't verify last command, status = %d", status); + return status; } *************** *** 568,574 **** * Delete a file from the NJB */ ! int njb_usb_delete(struct nomad_usb_data *nomad, char *file) { ! info("TODO: usb delete"); return 0; } --- 559,603 ---- * Delete a file from the NJB */ ! int njb_usb_delete(struct nomad_usb_data *njb, struct njbfs_fattr *fattr) { ! u_int16_t lsw, msw; ! char njb_status; ! int status; ! ! if ( !fattr->fileid ) ! return -ENOENT; ! ! ! lsw = LSW(fattr->fileid); ! msw = MSW(fattr->fileid); ! /* handshake, required for later set library counter */ ! status = njb_usb_handshake(njb); ! if ( status < 0 ) { ! err("handshake failed..."); ! return status; ! } ! ! /* setup phase */ ! status = njb_usb_control(njb, ! usb_rcvctrlpipe(njb->nomad_dev, ! NJB_ENDPOINT_CONTROL), ! NJB_CMD_DELETE_TRACK, ! UT_READ | USB_TYPE_VENDOR | ! USB_RECIP_OTHER, msw, lsw, &njb_status, 1, 3); ! ! if ( status < 0 ) { ! err("error sending delete message"); ! return status; ! } else if ( njb_status != NJB_OK ) { ! err("bad njb status = %d", njb_status); ! return -EIO; ! } ! ! status = njb_usb_update_library_counter(njb); ! if ( status < 0 ) { ! err("couldn't update library counter"); ! return -EIO; ! } ! return 0; } *************** *** 1224,1228 **** /* Set track id, return track */ memcpy(&header->trackid, &data[1], 4); ! dbg("write_track_tag: got new track id = %d", header->trackid); return 0; --- 1253,1257 ---- /* Set track id, return track */ memcpy(&header->trackid, &data[1], 4); ! printk("write_track_tag: got new track id = %d", header->trackid); return 0; *************** *** 1476,1480 **** return NULL; } ! } return track; --- 1505,1509 ---- return NULL; } ! *trackid = header.trackid; } return track; Index: njb_usb.h =================================================================== RCS file: /cvsroot/njbfs/njbfs/njb_usb.h,v retrieving revision 1.3.2.2 retrieving revision 1.3.2.3 diff -C2 -d -r1.3.2.2 -r1.3.2.3 *** njb_usb.h 24 Feb 2002 11:33:58 -0000 1.3.2.2 --- njb_usb.h 1 Mar 2002 09:15:40 -0000 1.3.2.3 *************** *** 158,161 **** --- 158,163 ---- extern int njb_usb_close(struct nomad_usb_data *njb, struct njbfs_fattr *fattr); + extern int njb_usb_close_no_release(struct nomad_usb_data *njb, + struct njbfs_fattr *fattr); extern int njb_usb_write(struct nomad_usb_data *njb, char *name, u_int32_t offset, u_int32_t count, void *buffer); *************** *** 163,167 **** extern int njb_usb_rename(struct nomad_usb_data *njb, struct njbfs_fattr *fattr); ! extern int njb_usb_delete(struct nomad_usb_data *njb, char *file); extern int njb_usb_create(struct nomad_usb_data *njb, char *file); extern int njb_usb_handshake(struct nomad_usb_data *njb); --- 165,169 ---- extern int njb_usb_rename(struct nomad_usb_data *njb, struct njbfs_fattr *fattr); ! extern int njb_usb_delete(struct nomad_usb_data *njb, struct njbfs_fattr *); extern int njb_usb_create(struct nomad_usb_data *njb, char *file); extern int njb_usb_handshake(struct nomad_usb_data *njb); Index: njbfs.h =================================================================== RCS file: /cvsroot/njbfs/njbfs/njbfs.h,v retrieving revision 1.4.2.2 retrieving revision 1.4.2.3 diff -C2 -d -r1.4.2.2 -r1.4.2.3 *** njbfs.h 24 Feb 2002 11:33:58 -0000 1.4.2.2 --- njbfs.h 1 Mar 2002 09:15:40 -0000 1.4.2.3 *************** *** 44,48 **** #define NJBFS_BLOCKSIZE_BITS 12 /* 2^x = blocksize */ ! #define NJBFS_ID3SIZE 8192 /* size of the false tag at the top */ #define NJBFS_FOOTERSIZE 4096 /* size of the zeroed footers at the bottom */ --- 44,48 ---- #define NJBFS_BLOCKSIZE_BITS 12 /* 2^x = blocksize */ ! #define NJBFS_ID3SIZE 4096 /* size of the false tag at the top */ #define NJBFS_FOOTERSIZE 4096 /* size of the zeroed footers at the bottom */ *************** *** 100,103 **** --- 100,104 ---- something that will require a reload? */ + struct njbfs_blockcache *bl_cache; }; Index: njbfs_cache.c =================================================================== RCS file: /cvsroot/njbfs/njbfs/njbfs_cache.c,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** njbfs_cache.c 26 Feb 2002 02:20:05 -0000 1.1.2.2 --- njbfs_cache.c 1 Mar 2002 09:15:40 -0000 1.1.2.3 *************** *** 112,116 **** } ! static void __njbfs_destroy_hashtable(njbfs_hash_element **table) { njbfs_hash_element *el, *last; --- 112,116 ---- } ! void __njbfs_destroy_hashtable(njbfs_hash_element **table) { njbfs_hash_element *el, *last; *************** *** 146,150 **** */ ! static int njbfs_add_hash_generic(njbfs_hash_element **table, char *id, void *data) { njbfs_hash_element *element; --- 146,150 ---- */ ! int njbfs_add_hash_generic(njbfs_hash_element **table, char *id, void *data) { njbfs_hash_element *element; *************** *** 172,176 **** ! static void* njbfs_get_hash_generic(njbfs_hash_element **table, char *id) { njbfs_hash_element *walk; --- 172,176 ---- ! void* njbfs_get_hash_generic(njbfs_hash_element **table, char *id) { njbfs_hash_element *walk; *************** *** 758,761 **** --- 758,763 ---- (fattr->size + (NJBFS_BLOCKSIZE - 1)) >> (NJBFS_BLOCKSIZE_BITS - 1); + + fattr->bl_cache = NULL; fattr->fileid = track->header.trackid; Index: njbfs_cache.h =================================================================== RCS file: /cvsroot/njbfs/njbfs/njbfs_cache.h,v retrieving revision 1.4.2.4 retrieving revision 1.4.2.5 diff -C2 -d -r1.4.2.4 -r1.4.2.5 *** njbfs_cache.h 26 Feb 2002 02:22:22 -0000 1.4.2.4 --- njbfs_cache.h 1 Mar 2002 09:15:40 -0000 1.4.2.5 *************** *** 214,217 **** --- 214,223 ---- struct njbfs_fattr_list *add_fattr_to_list(struct njbfs_fattr_list **, struct njbfs_fattr *); + void njbfs_destroy_fattr_cache(); + + + int njbfs_add_hash_generic(njbfs_hash_element **table, char *id, void *data); + void* njbfs_get_hash_generic(njbfs_hash_element **table, char *id); + void __njbfs_destroy_hashtable(njbfs_hash_element **); Index: njbfs_dir.c =================================================================== RCS file: /cvsroot/njbfs/njbfs/njbfs_dir.c,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -C2 -d -r1.1.2.2 -r1.1.2.3 *** njbfs_dir.c 26 Feb 2002 02:20:05 -0000 1.1.2.2 --- njbfs_dir.c 1 Mar 2002 09:15:40 -0000 1.1.2.3 *************** *** 60,67 **** switch (*ch) { case '/': - *ch = '_'; case '*': - *ch = '_'; case '?': *ch = '_'; } --- 60,67 ---- switch (*ch) { case '/': case '*': case '?': + case '>': + case '<': *ch = '_'; } *************** *** 223,226 **** --- 223,234 ---- gets a dirlist node (and creates a fattr struct) for our virtual directories + + BUGS: + We are unable to translate bad characters (?><) etc + in directory names for now... because we use + the directory name as a direct index into the hashtables. + + this should be easily cleaned once Jorge introduces the + njbfs_track structure. */ static void njbfs_dirlist_node_directories(struct njbfs_dirlist_node *p, *************** *** 299,302 **** --- 307,320 ---- /** * Get "/albums" directory entries from NJB cache + * + * Ok, albums are the trickiest thing to handle in a cache like this. + * we may have non-unique album names that we want to shove under + * one directory (eg _Unknown_), + * so we use a hashtable add/lookup method here to ensure + * uniqueness. + * + * sigh. + * + * */ int njbfs_load_albumsdir(struct njbfs_sb_info *info, *************** *** 305,309 **** --- 323,335 ---- struct njbfs_dirlist_node *p; struct njbfs_album_list *list; + int hash_size = sizeof(njbfs_hash_element *) * NJBFS_GENERIC_HASH_SIZE; + njbfs_hash_element **table = kmalloc(hash_size, GFP_KERNEL); + + if ( !table ) + return -ENOMEM; + + memset(table, 0, hash_size); + CHECK_FATTR_CACHE(info); *************** *** 316,326 **** --- 342,363 ---- return -ENOMEM; } + + if ( njbfs_get_hash_generic(table, list->album->name) ) + /* already found the album, skip. */ + continue; + + njbfs_add_hash_generic(table, list->album->name, (void *) 1); + memset(p, 0, sizeof(struct njbfs_dirlist_node)); + SAFE_STRDUP(p->entry.name, list->album->name); njbfs_dirlist_node_directories(p,info); + p->prev = NULL; p->next = dir->head; dir->head = p; } + + __njbfs_destroy_hashtable(table); return 0; } *************** *** 345,351 **** --- 382,391 ---- return -ENOMEM; } + memset(p, 0, sizeof(struct njbfs_dirlist_node)); + SAFE_STRDUP(p->entry.name, list->artist->name); njbfs_dirlist_node_directories(p, info); + p->prev = NULL; p->next = dir->head; *************** *** 375,380 **** --- 415,422 ---- } memset(p, 0, sizeof(struct njbfs_dirlist_node)); + SAFE_STRDUP(p->entry.name, list->genre->name); njbfs_dirlist_node_directories(p,info); + p->prev = NULL; p->next = dir->head; Index: njbfs_proc.h =================================================================== RCS file: /cvsroot/njbfs/njbfs/njbfs_proc.h,v retrieving revision 1.3.2.2 retrieving revision 1.3.2.3 diff -C2 -d -r1.3.2.2 -r1.3.2.3 *** njbfs_proc.h 24 Feb 2002 11:33:58 -0000 1.3.2.2 --- njbfs_proc.h 1 Mar 2002 09:15:40 -0000 1.3.2.3 *************** *** 22,26 **** int njbfs_proc_rename(struct njbfs_sb_info *, struct inode *, struct dentry *, struct inode *, struct dentry *); ! int njbfs_proc_unlink(struct njbfs_sb_info *, char *); int njbfs_proc_create(struct njbfs_sb_info *, char *, struct njbfs_fattr **); int njbfs_write(struct dentry *, unsigned long, unsigned long, char *); --- 22,26 ---- int njbfs_proc_rename(struct njbfs_sb_info *, struct inode *, struct dentry *, struct inode *, struct dentry *); ! int njbfs_proc_unlink(struct njbfs_sb_info *, struct dentry *); int njbfs_proc_create(struct njbfs_sb_info *, char *, struct njbfs_fattr **); int njbfs_write(struct dentry *, unsigned long, unsigned long, char *); Index: nomad.c =================================================================== RCS file: /cvsroot/njbfs/njbfs/nomad.c,v retrieving revision 1.3.2.1 retrieving revision 1.3.2.2 diff -C2 -d -r1.3.2.1 -r1.3.2.2 *** nomad.c 15 Feb 2002 20:07:32 -0000 1.3.2.1 --- nomad.c 1 Mar 2002 09:15:40 -0000 1.3.2.2 *************** *** 40,44 **** #include <linux/poll.h> #include <linux/init.h> ! #include <linux/malloc.h> #include <linux/spinlock.h> #include <linux/smp_lock.h> --- 40,44 ---- #include <linux/poll.h> #include <linux/init.h> ! #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/smp_lock.h> Index: proc.c =================================================================== RCS file: /cvsroot/njbfs/njbfs/proc.c,v retrieving revision 1.6.2.5 retrieving revision 1.6.2.6 diff -C2 -d -r1.6.2.5 -r1.6.2.6 *** proc.c 26 Feb 2002 02:23:38 -0000 1.6.2.5 --- proc.c 1 Mar 2002 09:15:40 -0000 1.6.2.6 *************** *** 4,7 **** --- 4,8 ---- * * Copyright (C) 2001 Jörg Prante <joe...@gm...> + * Copyright (C) 2002 Ben Osheroff <be...@gi...> * * based on ftpfs by Florin Malita <fm...@ya...> *************** *** 60,63 **** --- 61,65 ---- static int njbfs_parse_filename(struct njbfs_fattr *fattr, const char *file); + int njbfs_write_block_cache(struct dentry *dentry); unsigned char *k_parse_attribute(unsigned char *buf, unsigned char *key); *************** *** 244,247 **** --- 246,252 ---- } + /* + lock, unless the read is called from read_until + */ int njbfs_read_lock(struct inode *i) { *************** *** 309,313 **** { struct njbfs_fattr *f; - int status; if (njbfs_lock(info)) return NULL; --- 314,317 ---- *************** *** 374,377 **** --- 378,384 ---- } + /* + TODO: move this to iget + */ njb_inode_mark_closed(inode); njb_set_pos(inode, 0); *************** *** 403,410 **** } - - njbfs_lock(info); /* here's where we update the cache */ if ( fattr->update_cache ) { --- 410,418 ---- } njbfs_lock(info); + /* any pending writes? */ + njbfs_write_block_cache(dentry); + /* here's where we update the cache */ if ( fattr->update_cache ) { *************** *** 579,583 **** */ - #define PROFILE int njbfs_read_until(struct file *f, unsigned int fileid, char *name, u_int32_t until, char *buffer) --- 587,590 ---- *************** *** 587,594 **** struct inode *i = f->f_dentry->d_inode; - #ifdef PROFILE - time_t start = CURRENT_TIME; - int start_byte = njb_get_pos(i); - #endif if ( until == njb_get_pos(i) ) { --- 594,597 ---- *************** *** 626,640 **** } - #ifdef PROFILE - printk("pushed %d bytes in %d seconds\n", - until - start_byte, CURRENT_TIME - start); - #endif njb_interruption_inode = 0; return 0; } ! /* ! lock, unless the read is called from read_until */ /** --- 629,676 ---- } njb_interruption_inode = 0; return 0; } ! /** ! * If the specified dentry is different than the one we're ! * reading from currently, close down the read. */ + int njbfs_close_current(struct njbfs_sb_info *info, + struct inode *inode, + struct njbfs_fattr *fattr) + { + int status; + struct njbfs_fattr *opened_fattr; + struct dentry *current_dentry; + + if ( !info->njb->current_dentry ) + return 0; + + current_dentry = info->njb->current_dentry; + + opened_fattr = + njbfs_get_attr_nolock(current_dentry, info); + + if ( !opened_fattr ) + return -EINVAL; + + if (fattr->fileid != opened_fattr->fileid) { + /* mark the inode as closed (usually njbfs_close does this) */ + njb_inode_mark_closed(current_dentry->d_inode); + njb_set_pos(current_dentry->d_inode, 0); + + if ( + (status = + njb_usb_close_no_release(info->njb, opened_fattr))) { + if (status != NJB_NOT_CAPTURED) { + err("open: njb wouldn't close."); + njbfs_read_unlock(inode); + return -EIO; + } + } + } + return 0; + } /** *************** *** 651,659 **** { struct inode *inode = dentry->d_inode; - struct super_block *sb = inode->i_sb; struct njbfs_sb_info *info = ! (struct njbfs_sb_info *) sb->u.generic_sbp; struct nomad_usb_data *njb = info->njb; ! struct njbfs_fattr *fattr, *opened_fattr; char buf[NJBFS_MAXPATHLEN], name[NJBFS_MAXPATHLEN]; int bytes, status, faked = 0; --- 687,695 ---- { struct inode *inode = dentry->d_inode; struct njbfs_sb_info *info = ! (struct njbfs_sb_info *) inode->i_sb->u.generic_sbp; struct nomad_usb_data *njb = info->njb; ! struct njbfs_fattr *fattr; ! char buf[NJBFS_MAXPATHLEN], name[NJBFS_MAXPATHLEN]; int bytes, status, faked = 0; *************** *** 679,683 **** create_id3_tag(dentry, buffer); njb_set_pos(inode, 0); - dbg("faked the id3 header."); return NJBFS_BLOCKSIZE; } else if (offset < NJBFS_ID3SIZE) { --- 715,718 ---- *************** *** 685,693 **** njb_set_pos(inode, offset + NJBFS_BLOCKSIZE); memset(buffer, 0, NJBFS_BLOCKSIZE); - dbg("faked the 2nd block."); return NJBFS_BLOCKSIZE; } else if (fattr->size - offset == NJBFS_FOOTERSIZE) { memset(buffer, 0, NJBFS_BLOCKSIZE); - dbg("faked the last block."); return NJBFS_BLOCKSIZE; } else if (fattr->size - offset == NJBFS_FOOTERSIZE * 2) { --- 720,726 ---- *************** *** 700,734 **** return -EINTR; ! if (njb->current_dentry) { ! /* There's a file already open on the jukebox. ! if it's not us, close it down and open our file up. */ ! ! opened_fattr = njbfs_get_attr_nolock(njb->current_dentry, info); ! ! if ( !opened_fattr ) { ! njbfs_read_unlock(inode); ! return -EINVAL; ! } ! ! if (fattr->fileid != opened_fattr->fileid) { ! dbg ! ("closing '%s', opening '%s'", opened_fattr->title, fattr->title); ! ! ! /* mark the inode as closed (usually njbfs_close does this) */ ! njb_inode_mark_closed(njb->current_dentry->d_inode); ! njb_set_pos(njb->current_dentry->d_inode, 0); ! ! if ( ! (status = ! njb_usb_close_no_release(njb, opened_fattr))) { ! if (status != NJB_NOT_CAPTURED) { ! err("open: njb wouldn't close."); ! njbfs_read_unlock(inode); ! return -EIO; ! } ! } ! } ! } if (!njb_inode_is_open(inode)) { --- 733,739 ---- return -EINTR; ! status = njbfs_close_current(info, inode, fattr); ! if ( status ) ! return status; if (!njb_inode_is_open(inode)) { *************** *** 744,748 **** } - /* transfer */ /* this should detect if they're trying to seek in the file. --- 749,752 ---- *************** *** 753,756 **** --- 757,761 ---- njbfs_read_until(file, fattr->fileid, name, offset, buffer); + /* transfer */ if ( (bytes = *************** *** 768,773 **** } /** ! * Write to a file * * @param dentry directory entry to read from --- 773,953 ---- } + void destroy_block_cache(struct njbfs_fattr *fattr) + { + int i; + for(i=0; i < fattr->bl_cache->count; i++) + kfree(fattr->bl_cache->blocks[i].buffer); + + kfree(fattr->bl_cache); + fattr->bl_cache = NULL; + } + + /* + find a block in the given block cache. + returns the pointer offset if found, + -1 if not found + */ + int find_in_block_cache(struct njbfs_blockcache *bl, off_t offset) + { + int i; + for(i=0; i < bl->count; i++) { + if ( bl->blocks[i].offset == offset ) + return i; + } + return -1; + } + + int add_to_block_cache(struct njbfs_fattr *fattr, off_t offset, off_t size, char *buffer) + { + int index; + void *buf; + struct njbfs_blockcache *bl = fattr->bl_cache; + + if ( !fattr->bl_cache ) { + fattr->bl_cache = kmalloc(sizeof(struct njbfs_blockcache), GFP_KERNEL); + if ( !fattr->bl_cache ) { + err("couldn't kmalloc block cache"); + return -ENOMEM; + } + memset(fattr->bl_cache, 0, sizeof(struct njbfs_blockcache)); + fattr->bl_cache->count = 0; + bl = fattr->bl_cache; + } + + + + buf = kmalloc(size, GFP_KERNEL); + if ( !buf ) { + err("couldn't kmalloc block in cache"); + destroy_block_cache(fattr); + return -EINVAL; + } + + /* + see if we already have the block in cache + */ + index = find_in_block_cache(bl, offset); + if ( index == -1 ) { + if ( bl->count >= NJBFS_MAXBLOCKS ) { + err("file size too large, please increase NBFS_MAXBLOCKS"); + kfree(buf); + destroy_block_cache(fattr); + return -EINVAL; + } + memcpy(buf, buffer, size); + bl->blocks[bl->count].buffer = buf; + bl->blocks[bl->count].size = size; + bl->blocks[bl->count].offset = offset; + bl->count++; + } else { + kfree(bl->blocks[index].buffer); + memcpy(buf, buffer, size); + bl->blocks[index].buffer = buf; + bl->blocks[size].size = size; + bl->blocks[bl->count].offset = offset; + } + return 0; + } + + int njbfs_write_block_cache(struct dentry *dentry) + { + off_t offset, size; + int i, status; + struct njbfs_fattr *fattr; + struct njbfs_sb_info *info = + (struct njbfs_sb_info *) dentry->d_inode->i_sb->u.generic_sbp; + + fattr = njbfs_get_attr_nolock(dentry, info); + if ( !fattr ) + return -ENOENT; + + if ( !fattr->bl_cache || !fattr->bl_cache->count ) + return 0; + + + /* + calculate file size. + */ + for(i= 0, size = 0; i < fattr->bl_cache->count; i++) + size += fattr->bl_cache->blocks[i].size; + + + /* + make sure no read is in progress. + */ + status = njbfs_close_current(info, dentry->d_inode, fattr); + if ( status ) + return status; + + /* + give the real size of the file to open + so the nomad will know how much to expect + */ + fattr->size = size; + + /* + change to open_write + */ + status = njb_usb_open(info->njb, fattr); + if ( status ) + return status; + + + /* + now set the size to the ID3 faking size + */ + fattr->size = + size + NJBFS_ID3SIZE + NJBFS_FOOTERSIZE + + (NJBFS_BLOCKSIZE - (size % NJBFS_BLOCKSIZE)); + fattr->real_size = size; + + /* + set the cache to update. + */ + fattr->update_cache = 1; + + /* + do some tricky fun stuff here to + parse id3 headers and rewrite the file if there + was an old file, etc. + */ + + + for(i = 0; i < fattr->bl_cache->count; i++) { + offset = find_in_block_cache(fattr->bl_cache, i * NJBFS_BLOCKSIZE); + status = njb_usb_write(info->njb, fattr->title, + fattr->bl_cache->blocks[offset].offset, + fattr->bl_cache->blocks[offset].size, + fattr->bl_cache->blocks[offset].buffer); + if ( status < 0 ) { + destroy_block_cache(fattr); + njb_usb_close(info->njb, fattr); + return status; + } + } + + destroy_block_cache(fattr); + + status = njb_usb_close(info->njb, fattr); + + /* update library counter */ + dbg("write_block_cache: updating lib counter"); + status = njb_usb_update_library_counter(info->njb); + if (status < 0) { + err + ("close: updating lib count error, status = %d, ", + status); + return -EPROTO; + } + + if ( status < 0 ) + return status; + else + return 0; + + } + /** ! * Write to a file - actually, just add to the block cache. * * @param dentry directory entry to read from *************** *** 780,789 **** unsigned long count, char *buffer) { - struct inode *inode = dentry->d_inode; - struct super_block *sb = inode->i_sb; struct njbfs_sb_info *info = ! (struct njbfs_sb_info *) sb->u.generic_sbp; char buf[NJBFS_MAXPATHLEN], name[NJBFS_MAXPATHLEN]; ! int bytes; njbfs_get_name(dentry, buf); --- 960,969 ---- unsigned long count, char *buffer) { struct njbfs_sb_info *info = ! (struct njbfs_sb_info *) dentry->d_inode->i_sb->u.generic_sbp; ! ! struct njbfs_fattr *fattr; char buf[NJBFS_MAXPATHLEN], name[NJBFS_MAXPATHLEN]; ! int status; njbfs_get_name(dentry, buf); *************** *** 800,803 **** --- 980,993 ---- if (njbfs_lock(info)) return (-EINTR); + + fattr = njbfs_get_attr_nolock(dentry, info); + if ( !fattr ) { + err("couldn't find fattr"); + return -EINVAL; + } + + status = add_to_block_cache(fattr, offset, count, buffer); + + #if 0 if ( (bytes = *************** *** 808,819 **** return bytes; } njbfs_unlock(info); ! /* unload dir cache */ ! /* ! njbfs_cache_invalidate(dentry->d_parent); ! info("write: offset=%ld, count=%ld, bytes=%d", offset, count, bytes); ! */ ! return bytes; } --- 998,1009 ---- return bytes; } + #endif + njbfs_unlock(info); ! if ( status == 0 ) ! return count; ! else ! return status; } *************** *** 879,883 **** char old_buf[NJBFS_MAXPATHLEN + 6], new_buf[NJBFS_MAXPATHLEN + 6]; struct njbfs_fattr *old_fattr, *new_fattr; ! int status; njbfs_get_name(old_dentry, old_buf); --- 1069,1073 ---- char old_buf[NJBFS_MAXPATHLEN + 6], new_buf[NJBFS_MAXPATHLEN + 6]; struct njbfs_fattr *old_fattr, *new_fattr; ! int status = 0; njbfs_get_name(old_dentry, old_buf); *************** *** 940,961 **** * Delete a file */ ! int njbfs_proc_unlink(struct njbfs_sb_info *info, char *file) { ! char buf[NJBFS_MAXPATHLEN + 6]; int status; - if (strlen(info->mnt.root) + strlen(file) > NJBFS_MAXPATHLEN) { - err("unlink: path too long!"); - return -EINVAL; - } - sprintf(buf, "%s%s", info->mnt.root, file); - if (njbfs_lock(info)) return -EINVAL; ! if ((status = njb_usb_delete(info->njb, buf)) < 0) { err("unlink: couldn't delete file!"); status = -EIO; } njbfs_unlock(info); return status; --- 1130,1156 ---- * Delete a file */ ! int njbfs_proc_unlink(struct njbfs_sb_info *info, struct dentry *dentry) { ! struct njbfs_fattr *fattr; int status; if (njbfs_lock(info)) return -EINVAL; ! fattr = njbfs_get_attr_nolock(dentry, info); ! if ( ! fattr ) { ! err("couldn't find fattr."); ! njbfs_unlock(info); ! return -ENOENT; ! } ! ! if ((status = njb_usb_delete(info->njb, fattr)) < 0) { err("unlink: couldn't delete file!"); status = -EIO; } + + njbfs_remove_fattr(fattr); + njbfs_cache_empty(info); + njbfs_unlock(info); return status; Index: proc.h =================================================================== RCS file: /cvsroot/njbfs/njbfs/proc.h,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -C2 -d -r1.1.2.1 -r1.1.2.2 *** proc.h 24 Feb 2002 11:33:58 -0000 1.1.2.1 --- proc.h 1 Mar 2002 09:15:40 -0000 1.1.2.2 *************** *** 4,8 **** #include "nomad_usb.h" ! #define UNKNOWN_STRING "__unknown__" #endif --- 4,30 ---- #include "nomad_usb.h" ! /* ! This is about 24 MB worth of data. ! If more is needed, well... ! ! hmm. ! Maybe later we can add a "large_transfers" ! flag or something. ! */ ! ! #define NJBFS_MAXBLOCKS 6000 ! + struct njbfs_block { + off_t offset; + off_t size; + void *buffer; + }; + + struct njbfs_blockcache { + int count; + struct njbfs_block blocks[NJBFS_MAXBLOCKS]; + }; + + #define UNKNOWN_STRING "<Unknown>" #endif |