1.1 --- a/libfsserver/lib/files/ext2_file_operations.cc Sun Aug 29 23:51:48 2021 +0200
1.2 +++ b/libfsserver/lib/files/ext2_file_operations.cc Tue Aug 31 23:51:13 2021 +0200
1.3 @@ -155,6 +155,54 @@
1.4 ext2fs_file_write(file, addr, size, NULL);
1.5 }
1.6
1.7 +/* Obtain information for the given inode. */
1.8 +
1.9 +long Ext2FileOperations::read_inode(ext2_ino_t ino, struct ext2_inode *inode)
1.10 +{
1.11 + std::lock_guard<std::mutex> guard(_lock);
1.12 +
1.13 + if (ext2fs_read_inode(_fs, ino, inode))
1.14 + return -L4_EIO;
1.15 +
1.16 + return L4_EOK;
1.17 +}
1.18 +
1.19 +
1.20 +
1.21 +/* Directory iteration support. */
1.22 +
1.23 +/* Callback function invoking the callback method. */
1.24 +
1.25 +static int _directory_iterate_fn(struct ext2_dir_entry *dir_entry,
1.26 + int offset, int blocksize, char *buf,
1.27 + void *priv_data)
1.28 +{
1.29 + struct Ext2DirectoryIteration *data = reinterpret_cast<struct Ext2DirectoryIteration *>(priv_data);
1.30 +
1.31 + return data->ops->directory_iterate_fn(dir_entry, offset, blocksize, buf, data);
1.32 +}
1.33 +
1.34 +/* Callback method invoking the actual callback, with control over locking. */
1.35 +
1.36 +int Ext2FileOperations::directory_iterate_fn(struct ext2_dir_entry *dir_entry,
1.37 + int offset, int blocksize,
1.38 + char *buf, struct Ext2DirectoryIteration *priv_data)
1.39 +{
1.40 + /* Release the lock to allow other operations to proceed. */
1.41 +
1.42 + _lock.unlock();
1.43 +
1.44 + /* Invoke the actual callback function. */
1.45 +
1.46 + struct Ext2DirectoryIteration *data = reinterpret_cast<struct Ext2DirectoryIteration *>(priv_data);
1.47 + int result = data->func(dir_entry, offset, blocksize, buf, data->priv_data);
1.48 +
1.49 + /* Acquire the lock and continue iteration. */
1.50 +
1.51 + _lock.lock();
1.52 + return result;
1.53 +}
1.54 +
1.55 /* Initiate iteration over a directory, with the given 'func' being called
1.56 with directory entry details for each entry. */
1.57
1.58 @@ -163,20 +211,30 @@
1.59 char *, void *),
1.60 void *priv_data)
1.61 {
1.62 - if (ext2fs_dir_iterate(_fs, dir, 0, 0, func, priv_data))
1.63 - return -L4_EIO;
1.64 + /* NOTE: Iteration should probably be interrupted if it appears that the
1.65 + directory has been modified and the structure of the data has
1.66 + been changed. This condition might then cause iteration to begin
1.67 + again, skipping ahead to the entry after the last visited entry. */
1.68
1.69 - return L4_EOK;
1.70 -}
1.71 + /* Acquire the lock for iteration to proceed safely. */
1.72 +
1.73 + _lock.lock();
1.74
1.75 -long Ext2FileOperations::read_inode(ext2_ino_t ino_file, struct ext2_inode *inode)
1.76 -{
1.77 - std::lock_guard<std::mutex> guard(_lock);
1.78 + /* Begin iteration using the given callback function to invoke a callback
1.79 + method in this object that will wrap the actual callback with locking
1.80 + operations. */
1.81 +
1.82 + struct Ext2DirectoryIteration data = {this, func, priv_data};
1.83 + int result = ext2fs_dir_iterate(_fs, dir, 0, 0, _directory_iterate_fn, &data);
1.84
1.85 - if (ext2fs_read_inode(_fs, ino_file, inode))
1.86 + /* Release the lock upon finishing iteration. */
1.87 +
1.88 + _lock.unlock();
1.89 +
1.90 + if (result)
1.91 return -L4_EIO;
1.92 -
1.93 - return L4_EOK;
1.94 + else
1.95 + return L4_EOK;
1.96 }
1.97
1.98 // vim: tabstop=4 expandtab shiftwidth=4