1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
/**
* Copyright (c) 2008-2010 Alper Akcan <alper.akcan@gmail.com>
* Copyright (c) 2009-2010 Renzo Davoli <renzo@cs.unibo.it>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the fuse-ext2
* distribution in the file COPYING); if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "fuse-ext2.h"
int op_mkdir (const char *path, mode_t mode)
{
int rt;
time_t tm;
errcode_t rc;
char *p_path;
char *r_path;
ext2_ino_t ino;
struct ext2_inode inode;
struct fuse_context *ctx;
ext2_filsys e2fs;
FUSE_EXT2_LOCK;
e2fs = current_ext2fs();
debugf("enter");
debugf("path = %s, mode: 0%o, dir:0%o", path, mode, LINUX_S_IFDIR);
rt=do_check_split(path, &p_path ,&r_path);
if (rt != 0) {
debugf("do_check(%s); failed", path);
goto err;
}
debugf("parent: %s, child: %s, pathmax: %d", p_path, r_path, PATH_MAX);
rt = do_readinode(e2fs, p_path, &ino, &inode);
if (rt) {
debugf("do_readinode(%s, &ino, &inode); failed", p_path);
goto err_free_split;
}
do {
debugf("calling ext2fs_mkdir(e2fs, %d, 0, %s);", ino, r_path);
rc = ext2fs_mkdir(e2fs, ino, 0, r_path);
if (rc == EXT2_ET_DIR_NO_SPACE) {
debugf("calling ext2fs_expand_dir(e2fs, &d)", ino);
if (ext2fs_expand_dir(e2fs, ino)) {
debugf("error while expanding directory %s (%d)", p_path, ino);
rt = -ENOSPC;
goto err_free_split;
}
}
} while (rc == EXT2_ET_DIR_NO_SPACE);
if (rc) {
debugf("ext2fs_mkdir(e2fs, %d, 0, %s); failed (%d)", ino, r_path, rc);
debugf("e2fs: %p, e2fs->inode_map: %p", e2fs, e2fs->inode_map);
rt = -EIO;
goto err_free_split;
}
rt = do_readinode(e2fs, path, &ino, &inode);
if (rt) {
debugf("do_readinode(%s, &ino, &inode); failed", path);
rt = -EIO;
goto err_free_split;
}
tm = e2fs->now ? e2fs->now : time(NULL);
inode.i_mode = LINUX_S_IFDIR | mode;
inode.i_ctime = inode.i_atime = inode.i_mtime = tm;
ctx = fuse_get_context();
if (ctx) {
inode.i_uid = ctx->uid;
inode.i_gid = ctx->gid;
}
rc = ext2fs_write_inode(e2fs, ino, &inode);
if (rc) {
debugf("ext2fs_write_inode(e2fs, ino, &inode); failed");
rt = -EIO;
goto err_free_split;
}
/* update parent dir */
rt = do_readinode(e2fs, p_path, &ino, &inode);
if (rt) {
debugf("do_readinode(%s, &ino, &inode); dailed", p_path);
rt = -EIO;
goto err_free_split;
}
inode.i_ctime = inode.i_mtime = tm;
rc = ext2fs_write_inode(e2fs, ino, &inode);
if (rc) {
debugf("ext2fs_write_inode(e2fs, ino, &inode); failed");
rt = -EIO;
goto err_free_split;
}
free_split(p_path, r_path);
debugf("leave");
FUSE_EXT2_UNLOCK;
return 0;
err_free_split:
free_split(p_path, r_path);
err:
FUSE_EXT2_UNLOCK;
return rt;
}
|