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

Reply via email to