Module: ReiserFS

Included in:
FileObject
Defined in:
lib/fs/MiqFS/modules/ReiserFS.rb,
lib/fs/ReiserFS/block.rb,
lib/fs/ReiserFS/utils.rb,
lib/fs/ReiserFS/directory.rb,
lib/fs/ReiserFS/file_data.rb,
lib/fs/ReiserFS/superblock.rb,
lib/fs/ReiserFS/directory_entry.rb

Overview

Reiser file system interface to MiqFS.

Defined Under Namespace

Classes: Block, Directory, DirectoryEntry, FileData, FileObject, Superblock, Utils

Constant Summary collapse

SUPERBLOCK =
BinaryStruct.new([
  'V',  'num_blocks',         # The number of blocks in the partition
  'V',  'num_free_blocks',    # The number of free blocks in the partition
  'V',  'root_block',         # The block number of the block containing the root node
  'V',  'journal_block',      # The block number of the block containing the first journal node
  'V',  'journal_device',     # Journal device number
  'V',  'journal_original_size',  # Original journal size
  'V',  'journal_trans_max',  # The maximum number of blocks in a transaction
  'V',  'journal_magic',      # Journal magic number
  'V',  'journal_max_batch',  # The maximum number of blocks in a transaction
  'V',  'journal_max_commit_age',  # Time in seconds of how old an asynchronous commit can be
  'V',  'journal_max_trans_age',   # Time in seconds of how old a transaction can be
  'v',  'block_size',         # Block size
  'v',  'oid_max_size',       # The maximum size of the object id array
  'v',  'oid_current_size',   # The current size of the object id array
  'v',  'state',              # State of the partition: valid (1) or error (2)
  'a12', 'magic',              # Magic String
  'V',  'hash_code',          # The hash function that is being used to sort names in a directory
  'v',  'tree_height',        # The current height of the disk tree
  'v',  'bitmap_number',      # The amount of bitmap blocks needed to address each block of the file system
  'v',  'version',            # The reiserfs version number
  'a2', 'reserved',           #
  'V',  'inode_generation',   # Number of the current inode generation
])
SUPERBLOCK_SIZE =
SUPERBLOCK.size
SUPERBLOCK_OFFSET =
64 * 1024
DEF_CACHE_SIZE =

Default directory cache size.

50

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#cache_hitsObject

Members (these become members of an MiqFS instance).



15
16
17
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 15

def cache_hits
  @cache_hits
end

#dir_cacheObject

Members (these become members of an MiqFS instance).



15
16
17
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 15

def dir_cache
  @dir_cache
end

#entry_cacheObject

Members (these become members of an MiqFS instance).



15
16
17
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 15

def entry_cache
  @entry_cache
end

#rootDirObject

Members (these become members of an MiqFS instance).



15
16
17
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 15

def rootDir
  @rootDir
end

#superblockObject

Members (these become members of an MiqFS instance).



15
16
17
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 15

def superblock
  @superblock
end

Instance Method Details

#fs_dirEntries(p) ⇒ Object

Returns String array of all names, sans path.



81
82
83
84
85
86
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 81

def fs_dirEntries(p)
  # Get path directory.
  dir = ifs_getDir(p)
  return nil if dir.nil?
  dir.globNames
end

#fs_dirMkdir(_p) ⇒ Object

Make a directory. Parent must exist.



89
90
91
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 89

def fs_dirMkdir(_p)
  raise "Write functionality is not yet supported on ReiserFS."
end

#fs_dirRmdir(_p) ⇒ Object

Remove a directory.



94
95
96
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 94

def fs_dirRmdir(_p)
  raise "Write functionality is not yet supported on ReiserFS."
end

#fs_fileAtime(p) ⇒ Object

Returns Ruby Time object.



136
137
138
139
140
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 136

def fs_fileAtime(p)
  de = ifs_getFile(p)
  return nil if de.nil?
  de.aTime
end

#fs_fileAtime_obj(fobj) ⇒ Object

Returns a Ruby Time object.



169
170
171
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 169

def fs_fileAtime_obj(fobj)
  fobj.aTime
end

#fs_fileClose(_fobj) ⇒ Object

Write changes & destroy.



209
210
211
212
213
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 209

def fs_fileClose(_fobj)
  # TODO: unrem when write is supported.
  # fobj.data.close
  fobj = nil
end

#fs_fileCtime(p) ⇒ Object

Returns Ruby Time object.



143
144
145
146
147
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 143

def fs_fileCtime(p)
  de = ifs_getFile(p)
  return nil if de.nil?
  de.cTime
end

#fs_fileCtime_obj(fobj) ⇒ Object

Returns a Ruby Time object.



174
175
176
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 174

def fs_fileCtime_obj(fobj)
  fobj.cTime
end

#fs_fileDelete(_p) ⇒ Object

Delete file.



131
132
133
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 131

def fs_fileDelete(_p)
  raise "Write functionality is not yet supported on ReiserFS."
end

#fs_fileDirectory?(p) ⇒ Boolean

Returns true if name is a directory.

Returns:

  • (Boolean)


117
118
119
120
121
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 117

def fs_fileDirectory?(p)
  de = ifs_getFile(p)
  return false if de.nil?
  de.isDir?
end

#fs_fileExists?(p) ⇒ Boolean

Returns true if name exists, false if not.

Returns:

  • (Boolean)


103
104
105
106
107
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 103

def fs_fileExists?(p)
  de = ifs_getFile(p)
  return false if de.nil?
  true
end

#fs_fileFile?(p) ⇒ Boolean

Returns true if name is a regular file.

Returns:

  • (Boolean)


110
111
112
113
114
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 110

def fs_fileFile?(p)
  de = ifs_getFile(p)
  return false if de.nil?
  de.isFile?
end

#fs_fileMtime(p) ⇒ Object

Returns Ruby Time object.



150
151
152
153
154
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 150

def fs_fileMtime(p)
  de = ifs_getFile(p)
  return nil if de.nil?
  de.mTime
end

#fs_fileMtime_obj(fobj) ⇒ Object

Returns a Ruby Time obect.



179
180
181
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 179

def fs_fileMtime_obj(fobj)
  fobj.mTime
end

#fs_fileOpen(p, mode = "r") ⇒ Object

New FileObject instance. NOTE: FileObject must have access to Ext3 members. This is kind of like a ‘skip this’ thing. Ext3 methods use stuff owned by MiqFS, so this is necessary.



187
188
189
190
191
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 187

def fs_fileOpen(p, mode = "r")
  fobj = FileObject.new(p, self)
  fobj.open(mode)
  fobj
end

#fs_fileRead(fobj, len) ⇒ Object

Returns a Ruby String object.



199
200
201
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 199

def fs_fileRead(fobj, len)
  fobj.data.read(len)
end

#fs_fileSeek(fobj, offset, whence) ⇒ Object

Returns current file position.



194
195
196
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 194

def fs_fileSeek(fobj, offset, whence)
  fobj.data.seek(offset, whence)
end

#fs_fileSize(p) ⇒ Object

Returns size in bytes.



124
125
126
127
128
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 124

def fs_fileSize(p)
  de = ifs_getFile(p)
  return nil if de.nil?
  de.length
end

#fs_fileSize_obj(fobj) ⇒ Object

In these, fobj is a FileObject.



164
165
166
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 164

def fs_fileSize_obj(fobj)
  fobj.length
end

#fs_fileWrite(_fobj, _buf, _len) ⇒ Object



203
204
205
206
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 203

def fs_fileWrite(_fobj, _buf, _len)
  raise "Write functionality is not yet supported on ReiserFS."
  # fobj.data.write(buf, len)
end

#fs_freeBytesObject

Returns free space on file system in bytes.



72
73
74
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 72

def fs_freeBytes
  @superblock.freeBytes
end

#fs_initObject

File system interface.



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 59

def fs_init
  self.fsType = "ReiserFS"

  # Initialize bs & read root dir.
  @dobj.seek(0, IO::SEEK_SET)
  self.superblock  = Superblock.new(@dobj)
  self.rootDir     = Directory.new(superblock)
  self.entry_cache = LruHash.new(DEF_CACHE_SIZE)
  self.dir_cache   = LruHash.new(DEF_CACHE_SIZE)
  self.cache_hits  = 0
end

#fs_isSymLink?(p) ⇒ Boolean

Return true if p is a path to a symbolic link.

Returns:

  • (Boolean)


157
158
159
160
161
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 157

def fs_isSymLink?(p)
  de = ifs_getFile(p)
  return false if de.nil?
  de.isSymLink?
end

#ifs_getDir(p, miqfs = nil) ⇒ Object

Return a Directory object for a path. Raise error if path doesn’t exist.



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 270

def ifs_getDir(p, miqfs = nil)
  # If this is being called from a FileObject instance, then MiqFS owns contained instance members.
  # If this is being called from an ReiserFS module method, then self owns contained instance members.
  miqfs = self if miqfs.nil?

  # Wack leading drive.
  p = unnormalizePath(p)

  # Get an array of directory names, kill off the first (it's always empty).
  names = p.split(/[\\\/]/)
  names.shift

  dir = ifs_getDirR(names, miqfs)
  $log.info("Directory '#{p}' not found") if dir.nil?
  dir
end

#ifs_getDirR(names, miqfs) ⇒ Object

Return Directory recursively for given directory or nil if not exist.



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 288

def ifs_getDirR(names, miqfs)
  return miqfs.rootDir if names.empty?

  # Check for this path in the cache.
  fname = names.join('/')
  if miqfs.dir_cache.key?(fname)
    miqfs.cache_hits += 1
    return miqfs.dir_cache[fname]
  end

  name = names.pop
  pdir = ifs_getDirR(names, miqfs)
  return nil if pdir.nil?

  key = pdir.findKey(name)
  return nil if key.nil?

  dir = Directory.new(miqfs.superblock, key)
  return nil if dir.nil?

  miqfs.dir_cache[fname] = dir
end

#ifs_getFile(p, miqfs = nil) ⇒ Object

Return a DirectoryEntry for a given file or nil if not exist.



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 218

def ifs_getFile(p, miqfs = nil)
  # If this is being called from a FileObject instance, then MiqFS owns contained instance members.
  # If this is being called from an Ext3 module method, then self owns contained instance members.
  miqfs = self if miqfs.nil?

  # Preprocess path.
  p = unnormalizePath(p)
  dir, fname = File.split(p)
  # Fix for FB#835: if fname == root then fname needs to be "."
  fname = "." if fname == "/" || fname == "\\"

  # Check for this file in the cache.
  cache_name = "#{dir == '/' ? '' : dir}/#{fname}"
  if miqfs.entry_cache.key?(cache_name)
    miqfs.cache_hits += 1
    return miqfs.entry_cache[cache_name]
  end

  # Look for file in dir, but don't error if it doesn't exist.
  # NOTE: if p is a directory that's ok, find it.
  begin
    dirObj = ifs_getDir(dir, miqfs)
    dirEnt = dirObj.nil? ? nil : dirObj.findEntry(fname)
  rescue RuntimeError
    dirEnt = nil
  end

  miqfs.entry_cache[cache_name] = dirEnt
end

#ifs_putFile(p, miqfs = nil) ⇒ Object

Create a directory entry.



249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 249

def ifs_putFile(p, miqfs = nil)
  raise "Write functionality is not yet supported on ReiserFS."

  # Commented out for now to avoid unreachable code
  #
  # # If this is being called from a FileObject instance, then MiqFS owns contained instance members.
  # # If this is being called from an ReiserFS module method, then self owns contained instance members.
  # miqfs = self if miqfs.nil?

  # # Preprocess path.
  # p = unnormalizePath(p)
  # dir, fil = File.split(p)

  # # Parent directory must exist.
  # dirObj = ifs_getDir(dir, miqfs)
  # return nil if dir.nil?
  # dirObj.createFile(fil)
end

#unnormalizePath(p) ⇒ Object

Wack leading drive leter & colon.



312
313
314
# File 'lib/fs/MiqFS/modules/ReiserFS.rb', line 312

def unnormalizePath(p)
  p[1] == 58 ? p[2, p.size] : p
end