static int smb_refill_dir_cache(struct smb_server *server, struct inode *dir, unsigned long f_pos) { int result; static struct semaphore sem = MUTEX; int i; ino_t ino; do { down(&sem); result = smb_proc_readdir(server, dir, f_pos, SMB_READDIR_CACHE_SIZE, c_entry); if (result <= 0) { smb_invalid_dir_cache(dir->i_ino); up(&sem); return result; } c_seen_eof = (result < SMB_READDIR_CACHE_SIZE); c_dev = dir->i_dev; c_ino = dir->i_ino; c_size = result; c_last_returned_index = 0; ino = smb_fresh_inodes(server, c_size); for (i = 0; i < c_size; i++) { c_entry[i].f_ino = ino; ino += 1; } up(&sem); } while ((c_dev != dir->i_dev) || (c_ino != dir->i_ino)); return result; }
int smb_refill_dircache(struct cache_head * cachep, struct dentry *dentry) { struct inode * inode = dentry->d_inode; int result; VERBOSE("cache %s/%s, blocks=%d\n", DENTRY_PATH(dentry), cachep->pages); /* * Fill the cache, starting at position 2. */ retry: inode->u.smbfs_i.cache_valid |= SMB_F_CACHEVALID; result = smb_proc_readdir(dentry, 2, cachep); if (result < 0) { PARANOIA("readdir failed, result=%d\n", result); goto out; } /* * Check whether the cache was invalidated while * we were doing the scan ... */ if (!(inode->u.smbfs_i.cache_valid & SMB_F_CACHEVALID)) { PARANOIA("cache invalidated, retrying\n"); goto retry; } result = cachep->status; if (!result) { cachep->valid = 1; cachep->mtime = dentry->d_inode->i_mtime; } VERBOSE("cache %s/%s status=%d, entries=%d\n", DENTRY_PATH(dentry), cachep->status, cachep->entries); out: return result; }