Here is a patch for two minor matters.
- current get_uin() is hard to distinguish the error for the caller.
- writing persistent ino files may meet the file size limit. after
applying this patch, users should be careful about filesystem quota.
Junjiro Okajima
--- unionfs-20060131-1742/dirfops.c 2 Feb 2006 09:05:26 -0000 1.1
+++ unionfs-20060131-1742/dirfops.c 2 Feb 2006 12:36:22 -0000 1.2
@@ -68,15 +68,15 @@ static int unionfs_filldir(void *dirent,
off_t pos = rdstate2offset(buf->rdstate);
ino_t unionfs_ino = ino;
- if (stopd(buf->sb)->usi_persistent) {
- unionfs_ino = get_uin(buf->sb, buf->rdstate->uds_bindex,
- ino, O_CREAT);
- BUG_ON(unionfs_ino <= 0);
+ if (stopd(buf->sb)->usi_persistent)
+ err = read_uin(buf->sb, buf->rdstate->uds_bindex,
+ ino, O_CREAT, &unionfs_ino);
+ if (!err) {
+ err = buf->filldir(buf->dirent, name, namelen, pos,
+ unionfs_ino, d_type);
+ buf->rdstate->uds_offset++;
+ verify_rdstate_offset(buf->rdstate);
}
- err = buf->filldir(buf->dirent, name, namelen, pos,
- unionfs_ino, d_type);
- buf->rdstate->uds_offset++;
- verify_rdstate_offset(buf->rdstate);
}
/* If we did fill it, stuff it in our hash, otherwise return an error */
if (err) {
--- unionfs-20060131-1742/main.c 2 Feb 2006 09:05:26 -0000 1.1
+++ unionfs-20060131-1742/main.c 2 Feb 2006 12:36:22 -0000 1.2
@@ -84,12 +84,13 @@ int unionfs_interpose(struct dentry *den
} else {
ino_t ino;
/* get unique inode number for unionfs */
- if (stopd(sb)->usi_persistent)
- ino =
- get_uin(sb, bindex,
- dtohd_index(dentry, bindex)->d_inode->i_ino,
- O_CREAT);
- else
+ if (stopd(sb)->usi_persistent) {
+ err = read_uin(sb, bindex,
+ dtohd_index(dentry,
bindex)->d_inode->i_ino,
+ O_CREAT, &ino);
+ if (err)
+ goto out;
+ } else
ino = iunique(sb, UNIONFS_ROOT_INO);
inode = IGET(sb, ino);
--- unionfs-20060131-1742/persistent_inode.c 2 Feb 2006 09:05:26 -0000
1.1
+++ unionfs-20060131-1742/persistent_inode.c 2 Feb 2006 12:56:57 -0000
1.4
@@ -25,13 +25,17 @@ static ssize_t __fread(struct file *filp
{
int err;
mm_segment_t oldfs;
+ ssize_t (*func)(struct file*, char __user*, size_t, loff_t*);
+
+ func = do_sync_read;
+ if (filp->f_op && filp->f_op->read)
+ func = filp->f_op->read;
oldfs = get_fs();
set_fs(KERNEL_DS);
- if (filp->f_op->read)
- err = filp->f_op->read(filp, (char __user *)buf, size, pos);
- else
- err = do_sync_read(filp, (char __user *)buf, size, pos);
+ do {
+ err = func(filp, buf, size, pos);
+ } while (err == -EAGAIN || err == -EINTR);
set_fs(oldfs);
return err;
}
@@ -40,16 +44,28 @@ static ssize_t __fwrite(struct file *fil
{
int err;
mm_segment_t oldfs;
-
+ unsigned long flim;
+ struct rlimit *rl;
+ ssize_t (*func)(struct file*, const char __user*, size_t, loff_t*);
+
+ func = do_sync_write;
+ if (filp->f_op && filp->f_op->write)
+ func = filp->f_op->write;
+
+ /*
+ * it breaks RLIMIT_FSIZE,
+ * but users should be careful to quota.
+ */
+ rl = current->signal->rlim+RLIMIT_FSIZE;
+ flim = rl->rlim_cur;
+ rl->rlim_cur = RLIM_INFINITY;
oldfs = get_fs();
set_fs(KERNEL_DS);
- if (filp->f_op->write)
- err =
- filp->f_op->write(filp, (const char __user *)buf, size,
- pos);
- else
- err = do_sync_write(filp, (const char __user *)buf, size, pos);
+ do {
+ err = func(filp, buf, size, pos);
+ } while (err == -EAGAIN || err == -EINTR);
set_fs(oldfs);
+ rl->rlim_cur = flim;
return err;
}
@@ -442,8 +458,8 @@ int parse_imap_option(struct super_block
/*
* get @ino from @hidden_ino.
*/
-static int __get_uin(struct unionfs_sb_info *sbi, ino_t hidden_ino, int bindex,
- ino_t * ino)
+static int __read_uin(struct unionfs_sb_info *sbi, ino_t hidden_ino, int
bindex,
+ ino_t * ino)
{
int err;
struct file *rev;
@@ -521,7 +537,7 @@ static int __write_uin(struct unionfs_sb
}
/*
- * get_uin(struct super_block *sb, uint8_t branchnum, ino_t inode_number, int
flag)
+ * read_uin(struct super_block *sb, uint8_t branchnum, ino_t inode_number, int
flag, ino_t *uino)
* fsnum: branch to reference when getting the inode number
* inode_number: lower level inode number use to reference the proper inode.
* flag: if set to O_CREAT it will creat the entry if it doesent exist
@@ -529,10 +545,10 @@ static int __write_uin(struct unionfs_sb
* returns: the unionfs inode number either created or retrieved based on
* the information.
*/
-ino_t get_uin(struct super_block * sb, uint8_t branchnum, ino_t inode_number,
- int flag)
+int read_uin(struct super_block * sb, uint8_t branchnum, ino_t inode_number,
+ int flag, ino_t *uino)
{
- ino_t ino, err = 0;
+ int err = 0;
struct unionfs_sb_info *spd;
print_entry_location();
@@ -542,8 +558,8 @@ ino_t get_uin(struct super_block * sb, u
/* Find appropriate reverse map and then read from the required
position */
/* get it from the array. */
- err = __get_uin(spd, inode_number, branchnum, &ino);
- if (err || ino)
+ err = __read_uin(spd, inode_number, branchnum, uino);
+ if (err || *uino)
goto out;
err = -EIO;
@@ -553,16 +569,14 @@ ino_t get_uin(struct super_block * sb, u
/* If we haven't found an entry and we have the O_CREAT flag set we
want to
* create a new entry write it out to the file and return its index
*/
- ino = spd->usi_next_avail++;
+ *uino = spd->usi_next_avail++;
down(&sb->s_lock);
- err = __write_uin(spd, ino, branchnum, inode_number);
+ err = __write_uin(spd, *uino, branchnum, inode_number);
if (err)
spd->usi_next_avail--;
up(&sb->s_lock);
out:
- print_exit_status((int)err);
- if (!err)
- err = ino;
+ print_exit_status(err);
return err;
}
--- unionfs-20060131-1742/unionfs.h 2 Feb 2006 09:05:27 -0000 1.1
+++ unionfs-20060131-1742/unionfs.h 2 Feb 2006 12:54:26 -0000 1.3
@@ -755,8 +755,8 @@ struct fmapent {
};
/* Persistant Inode functions */
-extern ino_t get_uin(struct super_block *sb, uint8_t branchnum,
- ino_t inode_number, int flag);
+extern int read_uin(struct super_block *sb, uint8_t branchnum,
+ ino_t inode_number, int flag, ino_t *uino);
extern int write_uin(struct super_block *sb, ino_t ino, int bindex,
ino_t hidden_ino);
extern int get_lin(struct super_block *sb, ino_t inode_number,
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs