Changeset 5563

Show
Ignore:
Timestamp:
07/17/12 07:56:29 (7 years ago)
Author:
nitin
Message:

Fixed size issue for getdents; Modified the corresponding Unit test.

Location:
seattle/branches/nacl_repy/seattlelib
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • seattle/branches/nacl_repy/seattlelib/lind_fs_calls.py

    r5545 r5563  
    16121612 
    16131613 
    1614 def getdents_syscall(fd,quantity): 
     1614def getdents_syscall(fd, quantity): 
    16151615  """  
    16161616    http://linux.die.net/man/2/getdents 
     
    16241624  if fd not in filedescriptortable: 
    16251625    raise SyscallError("getdents_syscall","EBADF","Invalid file descriptor.") 
     1626 
     1627  # Sanitizing the Input, there are people who would send other types too. 
     1628  if not isinstance(quantity, (int, long)): 
     1629    raise SyscallError("getdents_syscall","EINVAL","Invalid type for buffer size.") 
     1630 
     1631  # This is the minimum number of bytes, that should be provided. 
     1632  if quantity < 24: 
     1633    raise SyscallError("getdents_syscall","EINVAL","Buffer size is too small.") 
    16261634 
    16271635  # Acquire the fd lock... 
     
    16391647       
    16401648    returninodefntuplelist = [] 
    1641     currentquantity = 0 
     1649    bufferedquantity = 0 
    16421650 
    16431651    # let's move the position forward... 
    16441652    startposition = filedescriptortable[fd]['position'] 
    1645  
    16461653    # return tuple with inode, name, type tuples... 
    16471654    for entryname,entryinode in list(filesystemmetadata['inodetable'][inode]['filename_to_inode_dict'].iteritems())[startposition:]: 
    1648       if currentquantity >= quantity: 
    1649         break 
    1650  
    16511655      # getdents returns the mode also (at least on Linux)... 
    16521656      entrytype = get_direnttype_from_mode(filesystemmetadata['inodetable'][entryinode]['mode']) 
    1653       returninodefntuplelist.append((entryinode,entryname,entrytype)) 
    1654       currentquantity=currentquantity + 1 
     1657 
     1658      # Get the size of each entry, the size should be a multiple of 8. 
     1659      # The size of each entry is determined by sizeof(struct linux_dirent) which is 20 bytes plus the length of name of the file. 
     1660      # So, size of each entry becomes : 21 => 24, 26 => 32, 32 => 32. 
     1661      currentquantity = (((20 + len(entryname)) + 7) / 8) * 8 
     1662 
     1663      # This is the overall size of entries parsed till now, if size exceeds given size, then stop parsing and return 
     1664      bufferedquantity += currentquantity 
     1665      if bufferedquantity > quantity: 
     1666        break 
     1667 
     1668      returninodefntuplelist.append((entryinode, entryname, entrytype, currentquantity)) 
    16551669 
    16561670    # and move the position along.   Go no further than the end... 
    1657     filedescriptortable[fd]['position'] = min(startposition+quantity, len(filesystemmetadata['inodetable'][inode]['filename_to_inode_dict'])) 
     1671    filedescriptortable[fd]['position'] = min(startposition + len(returninodefntuplelist),\ 
     1672      len(filesystemmetadata['inodetable'][inode]['filename_to_inode_dict'])) 
    16581673     
    16591674    return returninodefntuplelist 
  • seattle/branches/nacl_repy/seattlelib/tests/ut_lind_fs_getdents.py

    r5528 r5563  
    33from lind_fs_constants import * 
    44 
    5 # Let's add a few directories to the system and see if it works... 
    65lind_test_server._blank_fs_init() 
    76 
     7# Let's add a few directories to the system and see if it works... 
    88lind_test_server.mkdir_syscall('/bar',S_IRWXA) 
    9  
    109lind_test_server.mkdir_syscall('/bar/baz',S_IRWXA) 
    11  
    1210lind_test_server.mkdir_syscall('/bar/bap',0) 
    1311 
     12# Create a new file... 
    1413fd = lind_test_server.open_syscall('/bar/bam',O_CREAT,0) 
    15  
    1614lind_test_server.close_syscall(fd) 
    1715 
     16# Read the root directory... 
    1817rootfd = lind_test_server.open_syscall('/',0,0) 
    19 val = lind_test_server.getdents_syscall(rootfd, 10) 
    20 assert(val==[(3, 'bar', DT_DIR), (1, '..', DT_DIR), (1, '.', DT_DIR)]), "Found: %s"%(str(val)) 
     18val = lind_test_server.getdents_syscall(rootfd, 100) 
     19assert (val==[(3, 'bar', DT_DIR, 24), (1, '..', DT_DIR, 24),\ 
     20  (1, '.', DT_DIR, 24)]), "Found: %s"%(str(val)) 
    2121 
     22# Read the /bar directory... 
    2223barfd = lind_test_server.open_syscall('/bar',0,0) 
    23 val = lind_test_server.getdents_syscall(barfd, 10) 
    24 assert(val==[(6, 'bam', DT_REG), (4, 'baz', DT_DIR), (5, 'bap', DT_DIR), (1, '..', DT_DIR), (3, '.', DT_DIR)]) 
    2524 
    26 assert(lind_test_server.lseek_syscall(barfd,0,SEEK_SET) == 0) 
    27 assert(lind_test_server.getdents_syscall(barfd,1) == [(6, 'bam', DT_REG)]) 
    28 assert(lind_test_server.getdents_syscall(barfd,1) == [(4, 'baz', DT_DIR)]) 
     25# The buffer size is given small, only few entries are read.  
     26val = lind_test_server.getdents_syscall(barfd, 80) 
     27assert (val == [(6, 'bam', DT_REG, 24), (4, 'baz', DT_DIR, 24),\ 
     28  (5, 'bap', DT_DIR, 24)]), "Found: %s"%(str(val)) 
     29 
     30# Again call on the same FD, should continue parsing the /bar directory. 
     31val = lind_test_server.getdents_syscall(barfd, 80) 
     32assert (val == [(1, '..', DT_DIR, 24), (3, '.', DT_DIR, 24)]),\ 
     33  "Found: %s"%(str(val)) 
     34 
     35lind_test_server.close_syscall(rootfd) 
     36lind_test_server.close_syscall(barfd)