Merge branch 'master' of ssh://www.aleph1.co.uk/home/aleph1/git/yaffs2
[yaffs2.git] / direct / yaffsfs.c
index ddbdcdb65354743c00bc02efc70e8111044f6119..041287c1e77405a01ee575bb13a4906928fcf0a2 100644 (file)
@@ -826,10 +826,10 @@ int yaffsfs_do_write(int fd, const void *vbuf, unsigned int nbyte, int isPwrite,
                yaffsfs_SetError(-EINVAL);
                totalWritten=-1;
        } else if( h && obj){
-               if(isPwrite)
-                       startPos = offset;
                if(h->append)
                        startPos = yaffs_GetObjectFileLength(obj);
+               else if(isPwrite)
+                       startPos = offset;
                else
                        startPos = h->position;
 
@@ -1180,6 +1180,261 @@ int yaffs_fstat(int fd, struct yaffs_stat *buf)
        return retVal;
 }
 
+
+/* xattrib functions */
+
+
+static int yaffs_do_setxattr(const YCHAR *path, const char *name, const void *data, int size, int flags, int follow)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_FindObject(NULL,path,0);
+
+       if(follow)
+               obj = yaffsfs_FollowLink(obj,0);
+
+       if(obj) {
+               retVal = yaffs_SetXAttribute(obj,name,data,size,flags);
+               if(retVal< 0){
+                       yaffsfs_SetError(retVal);
+                       retVal = -1;
+               }
+       } else
+               /* todo error not found */
+               yaffsfs_SetError(-ENOENT);
+
+       yaffsfs_Unlock();
+
+       return retVal;
+
+}
+
+int yaffs_setxattr(const YCHAR *path, const char *name, const void *data, int size, int flags)
+{
+       return yaffs_do_setxattr(path, name, data, size, flags, 1);
+}
+
+int yaffs_lsetxattr(const YCHAR *path, const char *name, const void *data, int size, int flags)
+{
+       return yaffs_do_setxattr(path, name, data, size, flags, 0);
+}
+
+
+
+int yaffs_fsetxattr(int fd, const char *name, const void *data, int size, int flags)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
+
+       if(obj) {
+               retVal = yaffs_SetXAttribute(obj,name,data,size,flags);
+               if(retVal< 0){
+                       yaffsfs_SetError(retVal);
+                       retVal = -1;
+               }
+       } else
+               /* bad handle */
+               yaffsfs_SetError(-EBADF);
+
+       yaffsfs_Unlock();
+
+       return retVal;
+}
+
+static int yaffs_do_getxattr(const YCHAR *path, const char *name, void *data, int size, int follow)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_FindObject(NULL,path,0);
+
+       if(follow)
+               obj = yaffsfs_FollowLink(obj,0);
+
+       if(obj) {
+               retVal = yaffs_GetXAttribute(obj,name,data,size);
+               if(retVal< 0){
+                       yaffsfs_SetError(retVal);
+                       retVal = -1;
+               }
+       } else
+               /* todo error not found */
+               yaffsfs_SetError(-ENOENT);
+
+       yaffsfs_Unlock();
+
+       return retVal;
+
+}
+
+int yaffs_getxattr(const YCHAR *path, const char *name, void *data, int size)
+{
+       return yaffs_do_getxattr( path, name, data, size, 1);
+}
+int yaffs_lgetxattr(const YCHAR *path, const char *name, void *data, int size)
+{
+       return yaffs_do_getxattr( path, name, data, size, 0);
+}
+
+
+
+int yaffs_fgetxattr(int fd, const char *name, void *data, int size)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
+
+       if(obj) {
+               retVal = yaffs_GetXAttribute(obj,name,data,size);
+               if(retVal< 0){
+                       yaffsfs_SetError(retVal);
+                       retVal = -1;
+               }
+       } else
+               /* bad handle */
+               yaffsfs_SetError(-EBADF);
+
+       yaffsfs_Unlock();
+
+       return retVal;
+}
+
+static int yaffs_do_listxattr(const YCHAR *path, char *data, int size, int follow)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_FindObject(NULL,path,0);
+
+       if(follow)
+               obj = yaffsfs_FollowLink(obj,0);
+
+       if(obj) {
+               retVal = yaffs_ListXAttributes(obj, data,size);
+               if(retVal< 0){
+                       yaffsfs_SetError(retVal);
+                       retVal = -1;
+               }
+       } else
+               /* todo error not found */
+               yaffsfs_SetError(-ENOENT);
+
+       yaffsfs_Unlock();
+
+       return retVal;
+
+}
+
+int yaffs_listxattr(const YCHAR *path, char *data, int size)
+{
+       return yaffs_do_listxattr(path, data, size, 1);
+}
+
+int yaffs_llistxattr(const YCHAR *path, char *data, int size)
+{
+       return yaffs_do_listxattr(path, data, size, 0);
+}
+
+int yaffs_flistxattr(int fd, char *data, int size)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
+
+       if(obj) {
+               retVal = yaffs_ListXAttributes(obj,data,size);
+               if(retVal< 0){
+                       yaffsfs_SetError(retVal);
+                       retVal = -1;
+               }
+       } else
+               /* bad handle */
+               yaffsfs_SetError(-EBADF);
+
+       yaffsfs_Unlock();
+
+       return retVal;
+}
+
+static int yaffs_do_removexattr(const YCHAR *path, const char *name, int follow)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_FindObject(NULL,path,0);
+
+       if(follow)
+               obj = yaffsfs_FollowLink(obj,0);
+
+       if(obj) {
+               retVal = yaffs_RemoveXAttribute(obj,name);
+               if(retVal< 0){
+                       yaffsfs_SetError(retVal);
+                       retVal = -1;
+               }
+       } else
+               /* todo error not found */
+               yaffsfs_SetError(-ENOENT);
+
+       yaffsfs_Unlock();
+
+       return retVal;
+
+}
+
+int yaffs_removexattr(const YCHAR *path, const char *name)
+{
+       return yaffs_do_removexattr(path, name, 1);
+}
+
+int yaffs_lremovexattr(const YCHAR *path, const char *name)
+{
+       return yaffs_do_removexattr(path, name, 0);
+}
+
+int yaffs_fremovexattr(int fd, const char *name)
+{
+       yaffs_Object *obj;
+
+       int retVal = -1;
+
+       yaffsfs_Lock();
+       obj = yaffsfs_GetHandleObject(fd);
+
+       if(obj){
+               retVal = yaffs_RemoveXAttribute(obj,name);
+               if(retVal< 0){
+                       yaffsfs_SetError(retVal);
+                       retVal = -1;
+               }
+       }else
+               /* bad handle */
+               yaffsfs_SetError(-EBADF);
+
+       yaffsfs_Unlock();
+
+       return retVal;
+}
+
 #ifdef CONFIG_YAFFS_WINCE
 int yaffs_get_wince_times(int fd, unsigned *wctime, unsigned *watime, unsigned *wmtime)
 {
@@ -1591,7 +1846,7 @@ int yaffs_inodecount(const YCHAR *path)
        yaffsfs_Lock();
        dev = yaffsfs_FindDevice(path,&dummy);
        if(dev  && dev->isMounted) {
-          int nObjects = dev->nObjectsCreated - dev->nFreeObjects;
+          int nObjects = dev->nObjects;
           if(nObjects > dev->nHardLinks)
                retVal = nObjects - dev->nHardLinks;
        }