[PATCH] udf: fix uid/gid options and add uid/gid=ignore and forget options
authorPhillip Susi <psusi@cfl.rr.com>
Wed, 8 Mar 2006 05:55:24 +0000 (21:55 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Wed, 8 Mar 2006 22:14:00 +0000 (14:14 -0800)
Fix a bug in udf where it would write uid/gid = 0 to the disk for files
owned by the id given with the uid=/gid= mount options.  It also adds 4 new
mount options: uid/gid=forget and uid/gid=ignore.  Without any options the
id in core and on disk always match.  Giving uid/gid=nnn specifies a
default ID to be used in core when the on disk ID is -1.  uid/gid=ignore
forces the in core ID to allways be used no matter what the on disk ID is.
uid/gid=forget forces the on disk ID to always be written out as -1.

The use of these options allows you to override ownerships on a disk or
disable ownwership information from being written, allowing the media to be
used portably between different computers and possibly different users
without permissions issues that would require root to correct.

Signed-off-by: Phillip Susi <psusi@cfl.rr.com>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/udf/inode.c
fs/udf/super.c
fs/udf/udf_sb.h

index 395e582ee5425cab1ad65177d5f8c02bedc9e932..d04cff2273b681a9944f3a319af83114340341cb 100644 (file)
@@ -1045,10 +1045,14 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
        }
 
        inode->i_uid = le32_to_cpu(fe->uid);
-       if ( inode->i_uid == -1 ) inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
+       if (inode->i_uid == -1 || UDF_QUERY_FLAG(inode->i_sb,
+                                       UDF_FLAG_UID_IGNORE))
+               inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
 
        inode->i_gid = le32_to_cpu(fe->gid);
-       if ( inode->i_gid == -1 ) inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
+       if (inode->i_gid == -1 || UDF_QUERY_FLAG(inode->i_sb,
+                                       UDF_FLAG_GID_IGNORE))
+               inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
 
        inode->i_nlink = le16_to_cpu(fe->fileLinkCount);
        if (!inode->i_nlink)
@@ -1335,10 +1339,14 @@ udf_update_inode(struct inode *inode, int do_sync)
                return err;
        }
 
-       if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid)
+       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
+               fe->uid = cpu_to_le32(-1);
+       else if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid)
                fe->uid = cpu_to_le32(inode->i_uid);
 
-       if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid)
+       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
+               fe->gid = cpu_to_le32(-1);
+       else if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid)
                fe->gid = cpu_to_le32(inode->i_gid);
 
        udfperms =      ((inode->i_mode & S_IRWXO)     ) |
index 4a6f49adc609b051b16bea2e5e59d7719b1e5ed7..368d8f81fe54777c8c0f3a6e2e9d7aac2b912562 100644 (file)
@@ -269,7 +269,7 @@ enum {
        Opt_gid, Opt_uid, Opt_umask, Opt_session, Opt_lastblock,
        Opt_anchor, Opt_volume, Opt_partition, Opt_fileset,
        Opt_rootdir, Opt_utf8, Opt_iocharset,
-       Opt_err
+       Opt_err, Opt_uforget, Opt_uignore, Opt_gforget, Opt_gignore
 };
 
 static match_table_t tokens = {
@@ -282,6 +282,10 @@ static match_table_t tokens = {
        {Opt_adinicb, "adinicb"},
        {Opt_shortad, "shortad"},
        {Opt_longad, "longad"},
+       {Opt_uforget, "uid=forget"},
+       {Opt_uignore, "uid=ignore"},
+       {Opt_gforget, "gid=forget"},
+       {Opt_gignore, "gid=ignore"},
        {Opt_gid, "gid=%u"},
        {Opt_uid, "uid=%u"},
        {Opt_umask, "umask=%o"},
@@ -414,6 +418,18 @@ udf_parse_options(char *options, struct udf_options *uopt)
                                uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
                                break;
 #endif
+                       case Opt_uignore:
+                               uopt->flags |= (1 << UDF_FLAG_UID_IGNORE);
+                               break;
+                       case Opt_uforget:
+                               uopt->flags |= (1 << UDF_FLAG_UID_FORGET);
+                               break;
+                       case Opt_gignore:
+                           uopt->flags |= (1 << UDF_FLAG_GID_IGNORE);
+                               break;
+                       case Opt_gforget:
+                           uopt->flags |= (1 << UDF_FLAG_GID_FORGET);
+                               break;
                        default:
                                printk(KERN_ERR "udf: bad mount option \"%s\" "
                                                "or missing value\n", p);
index 663669810be60afbae65f2a262a657f98bfa7f64..110f8d62616f4fa513c0fbd123e7292e92793faf 100644 (file)
 #define UDF_FLAG_VARCONV               8
 #define UDF_FLAG_NLS_MAP               9
 #define UDF_FLAG_UTF8                  10
+#define UDF_FLAG_UID_FORGET     11    /* save -1 for uid to disk */
+#define UDF_FLAG_UID_IGNORE     12    /* use sb uid instead of on disk uid */
+#define UDF_FLAG_GID_FORGET     13
+#define UDF_FLAG_GID_IGNORE     14
 
 #define UDF_PART_FLAG_UNALLOC_BITMAP   0x0001
 #define UDF_PART_FLAG_UNALLOC_TABLE    0x0002